scrapy實戰之spider篇
在我看來,使用scrapy架構相較于直接用python爬蟲庫的優點有兩個
第一是scrapy更加有效率,而爬蟲自然最注重的是效率
第二是scrapy将爬蟲的過程分成子產品化,使爬蟲抓取過程更加清晰
scrapy主要有三個子產品spider,pipeline,items.其中items代表的是容器(儲存所需要爬取的資料),
spider代表的是爬蟲子產品(将爬取的html内容用Xpath或者bs或者正規表達式解析,并且儲存在容器中),
pipeline代表的是資料處理子產品(eg.資料去重,資料清洗,資料儲存在mysql資料庫)
現在開始爬取資料
首先是建立scrapy項目
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2Lc1TPB50MVpWT0MGVNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39zM3EDN1YTNxITMygDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
然後開始寫爬蟲
第一是要明确需求,觀察網頁
分析的要爬取的字段有職位名(job),公司(company),地點(place),薪資(salary),
最高薪資(highest_salary),最低薪資(lowest_salary),釋出時間(time)
再檢查html網頁,分析網頁結構
分析得每段資料都是用div區分,而這種html結構用xpath解析比較友善
爬蟲解析方法主流的有三種,bs和xpath和正規表達式,其中正規表達式效率最高但是難度也是最大的,xpath難度中等,bs較簡單也是效率最低的
下面簡單介紹下xpath
主要為/ 和//
//代表無論該節點的位置,均找到它
/代表找節點的子節點,注意不能找子孫節點
@表示屬性
eg.//div[@class=”el”]代表的找到屬性為el的所有div節點下的所有元素
下面有一段html大家可以練習
‘
<html>
<head>
<title>春晚</title>
</head>
<body>
<h1 name="title">個人簡介</h1>
<div name="desc">
<p name="name">姓名:<span>小嶽嶽</span></p>
<p name="addr">住址:中國 河南</p>
<p name="info">代表作:五環之歌</p>
</div>’‘
‘
然後講解實戰内容,先貼出spider代碼
需要在python中進入項目目錄再編寫
“`
-- coding: utf-8 --
導入子產品
import scrapy
from job.items import JobItem #第一個錯誤
class XsSpider(scrapy.Spider):
name = ‘xs’
allowed_domains = [‘51job.com’]
start_urls = [‘
extract() 擷取到網頁标簽的内容,傳回清單
zw = item.xpath('p/span/a/text()').extract() # 職位
gs = item.xpath('span[@class="t2"]/a/text()').extract() # 公司名稱
dd = item.xpath('span[@class="t3"]/text()').extract() # 地點
xz = item.xpath('span[@class="t4"]/text()').extract() # 薪資
rt = item.xpath('span[@class="t5"]/text()').extract() # 釋出時間
href = item.xpath('p[@class="t1 "]/span/a/@href').extract() # 詳細頁面連接配接
# 資料存儲
if zw:
item_1['job'] = zw[0]
else:
item_1['job'] = ''
if gs:
item_1['company'] = gs[0]
else:
item_1['company'] = ''
if dd:
item_1['place'] = dd[0]
else:
item_1['place'] = '-'
if xz:
item_1['salary'] = xz[0]
else:
item_1['salary'] = ''
if rt:
item_1['time'] = rt[0]
else:
item_1['time'] = ''
if href:
item_1['href'] = href[0]
yield item_1
# 取下一頁的資料hred以清單形式
# 取下一頁的資料hred以清單形式
# 跳轉到下一頁
# 錯誤的原因是沒有注意縮進,導緻邏輯錯誤,跳轉是要在讀取完一個頁面後才能跳轉 不能在for循環内
next_page = response.xpath('//div[@class="dw_page"]//ul/li[last()]/a/@href').extract()
if next_page:
# 從清單中取到下一頁的連接配接
next_page_href = next_page[0]
# url:請求下一頁的url
# callback:函數回調,請求到内容後調用哪個函數,寫函數名
yield scrapy.Request(url=next_page_href, callback=self.parse,dont_filter=True)
`
針對一些複雜不易了解的地方進行講解
main的作用是儲存xpath解析到的内容,傳回的是清單内容。是以要用for語句周遊,
JobItem()是容器,是從item中導入的,需要在周遊裡面接受周遊的内容
if語句是防止用xpath解析的字段是空的,會導緻後面的字段占位,是以需要用if語句判斷字段是否是空的,如果是空的賦給它空字元串占位,如果不是空就占位
這一步很重要,如果不做if判斷會造成資料錯位
對于yield
yield是python的生成器,與return相似,但是這裡需要用yield而不能用return,因為return是每循環一次傳回一次值,沒有記憶儲存功能,yield具有記憶儲存功能,它不傳回值而是記憶該值并儲存在容器中,而這正是我們需要的
這個是調用下一頁,翻頁的功能
可以調用模闆,注意callback函數就好
下一篇是pipelines代碼部分的講解
有需要爬蟲資料的可以call我