初窺Scrapy
Scrapy是一個為了爬取網(wǎng)站數(shù)據(jù),提取結(jié)構(gòu)性數(shù)據(jù)而編寫的應(yīng)用框架郑什。 可以應(yīng)用在包括數(shù)據(jù)挖掘秧荆,信息處理或存儲歷史數(shù)據(jù)等一系列的程序中宴卖。其最初是為了 頁面抓取 (更確切來說, 網(wǎng)絡(luò)抓取 )所設(shè)計的县踢, 也可以應(yīng)用在獲取API所返回的數(shù)據(jù)(例如 Amazon Associates Web Services ) 或者通用的網(wǎng)絡(luò)爬蟲瘸彤。
基本步驟
選擇一個網(wǎng)站
定義您想抓取的數(shù)據(jù)
編寫提取數(shù)據(jù)的Spider
執(zhí)行spider,獲取數(shù)據(jù)
查看提取到的數(shù)據(jù)
安裝
控制臺執(zhí)行命令pip install Scrapy,如果執(zhí)行過程中出現(xiàn)building'twisted.test.raiser' extension error: Microsoft Visual C++ 14.0 is required.則需要在網(wǎng)站https://www.lfd.uci.edu/~gohlke/pythonlibs/#twisted下載whl文件详羡,pip安裝仍律,再重新運(yùn)行pip install Scrapy,即可
image.png
原理
Scrapy 使用 Twisted這個異步網(wǎng)絡(luò)庫來處理網(wǎng)絡(luò)通訊实柠,架構(gòu)清晰,并且包含了各種中間件接口善涨,可以靈活的完成各種需求窒盐。
原理
綠線是數(shù)據(jù)流向草则,首先從初始URL開始,Scheduler會將其交給Downloader進(jìn)行下載蟹漓,下載之后會交給Spider進(jìn)行分析炕横,Spider分析出來的結(jié)果有兩種:一種是需要進(jìn)一步抓取的鏈接,例如之前分析的“下一頁”的鏈接葡粒,這些東西會被傳回Scheduler份殿;另一種是需要保存的數(shù)據(jù),它們則被送到Item Pipeline那里嗽交,那是對數(shù)據(jù)進(jìn)行后期處理(詳細(xì)分析卿嘲、過濾、存儲等)的地方夫壁。另外拾枣,在數(shù)據(jù)流動的通道里還可以安裝各種中間件,進(jìn)行必要的處理盒让。
組成部分介紹:
Scrapy Engine:
負(fù)責(zé)組件之間數(shù)據(jù)的流轉(zhuǎn)梅肤,當(dāng)某個動作發(fā)生時觸發(fā)事件
Scheduler:
接收requests,并把他們?nèi)腙犚厍眩员愫罄m(xù)的調(diào)度
Downloader:
負(fù)責(zé)抓取網(wǎng)頁姨蝴,并傳送給引擎,之后抓取結(jié)果將傳給spider
Spiders:
用戶編寫的可定制化的部分肺缕,負(fù)責(zé)解析response似扔,產(chǎn)生items和URL。每一個spider代表一個特定的任務(wù)
Item Pipeline:
負(fù)責(zé)處理item搓谆,典型的用途:清洗炒辉、驗證、持久化
Downloader middlewares:
位于引擎和下載器之間的一個鉤子泉手,處理傳送到下載器的requests和傳送到引擎的response(若需要在Requests到達(dá)Downloader之前或者是responses到達(dá)spiders之前做一些預(yù)處理黔寇,可以使用該中間件來完成)
Spider middlewares:
位于引擎和抓取器之間的一個鉤子,處理抓取器的輸入和輸出
(在spiders產(chǎn)生的Items到達(dá)Item Pipeline之前做一些預(yù)處理或response到達(dá)spider之前做一些處理)
一個小例子
創(chuàng)建項目
在開始爬取之前斩萌,您必須創(chuàng)建一個新的Scrapy項目缝裤。 進(jìn)入您打算存儲代碼的目錄中,運(yùn)行下列命令:scrapy startproject book
創(chuàng)建項目
這些文件分別是:
scrapy.cfg: 項目的配置文件
book/: 該項目的python模塊颊郎。之后您將在此加入代碼憋飞。
book/items.py: 項目中的item文件.
book/pipelines.py: 項目中的pipelines文件.
book/settings.py: 項目的設(shè)置文件.
book/spiders/: 放置spider代碼的目錄.
建立spider
首先要進(jìn)入book目錄,使用basic模板創(chuàng)建一個spider
建立spider, scrapy genspider douban https://book.douban.com/top250?start=0
spider
pycharm 調(diào)試scrapy
建立一個main.py文件姆吭,在book文件目錄下,保證main.py和自動生成的scrapy.cfg在同一層,寫入下面代碼榛做。此文件是為了方便再pycharm中調(diào)試scrapy,提高開發(fā)效率
from scrapy.cmdline import execute
import sys,os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
execute(['scrapy','crawl','douban'])
scrapy crawl douban即啟動,名字為douban的spider
修改setting.py
將setting.py中的遵循robot協(xié)議改為False检眯,否則會過濾掉一些url
# Obey robots.txt rules
ROBOTSTXT_OBEY = False
模擬瀏覽器訪問
USER_AGENT = 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:45.0) Gecko/20100101 Firefox/45.0'
提取想要的內(nèi)容
xpath方式提取
xpath簡介
xpath使用路徑表達(dá)式在xml和html中進(jìn)行導(dǎo)航厘擂。
xpath包含標(biāo)準(zhǔn)函數(shù)庫。
xpath是一個w3c的標(biāo)準(zhǔn)锰瘸。
xpath節(jié)點(diǎn)關(guān)系
父節(jié)點(diǎn)
子節(jié)點(diǎn)
同胞節(jié)點(diǎn)
先輩節(jié)點(diǎn)
后代節(jié)點(diǎn)
xpath語法
image.png
image.png
image.png
extract_first()是為了防止extract()[0]不存在的時候報錯
name = node.xpath('td[2]/div[1]/a/text()').extract_first().strip()
summary = node.xpath('td[2]/p[2]/span/text()').extract_first()
在Shell中嘗試Selector選擇器
一直在pycharm調(diào)試xpath太復(fù)雜了刽严,因此scrapy提供shell方便測試語法。首先您需要進(jìn)入項目的根目錄避凝,執(zhí)行下列命令來啟動shell:scrapy shell "http://www.dmoz.org/Computers/Programming/Languages/Python/Books/"
注意:當(dāng)在終端運(yùn)行Scrapy時舞萄,請一定記得給url地址加上引號,否則包含參數(shù)的url(例如 & 字符)會導(dǎo)致Scrapy運(yùn)行失敗管削。
css方式提取
image.png
image.png
image.png
定義Item
Item 是保存爬取到的數(shù)據(jù)的容器倒脓;其使用方法和python字典類似, 并且提供了額外保護(hù)機(jī)制來避免拼寫錯誤導(dǎo)致的未定義字段錯誤佩谣。類似在ORM中做的一樣把还,您可以通過創(chuàng)建一個 scrapy.Item 類, 并且定義類型為 scrapy.Field 的類屬性來定義一個Item茸俭。 (如果不了解ORM, 不用擔(dān)心吊履,您會發(fā)現(xiàn)這個步驟非常簡單)。首先根據(jù)需要從book獲取到的數(shù)據(jù)對item進(jìn)行建模调鬓。 我們需要從book中獲取名字艇炎,描述。 對此腾窝,在item中定義相應(yīng)的字段缀踪。編輯 book目錄中的 items.py 文件:
class BookItem(scrapy.Item):
? ? # define the fields for your item here like:
? ? name = scrapy.Field()
? ? summary = scrapy.Field()
? ? pass
代碼
GitHub地址https://github.com/zhangpu1211/scrapy
可能遇到的錯誤
No modle named ‘win32api’
解決方案:pip install -i https://pypi.douban.com/simple/ pypiwin32
為什么有時候自己寫的xpath明明對的,卻獲取不到數(shù)據(jù)虹脯?
原因:F12產(chǎn)生的源碼驴娃,不同于網(wǎng)頁源代碼,前者可能是js加載完的源代碼循集。response.xpath()是根據(jù)網(wǎng)頁源代碼來提取信息的唇敞。
UserWarning: You do not have a working installation of the service_identity module: 'cannot import name 'opentype''.
解決方案:pip install service_identity --force --upgrade
csv文件輸出空一行
在python中的Lib\site-packages\scrapy,編輯該路徑下的exporters.py文件咒彤,并修改如下內(nèi)容:
image.png
csv文件中文亂碼
用sublime打開文件--以...編碼保存--UTF-8 with BOM