爬蟲框架Scrapy學(xué)習(xí)筆記

這些都是原來在微博上的文章,慢慢搬到這里吧

(一)安裝和測試

學(xué)習(xí)網(wǎng)絡(luò)爬蟲也是進(jìn)行自然語言處理的前期準(zhǔn)備工作虑润,爬蟲是獲取大量語料的利器?瓢对,自從學(xué)會(huì)使用網(wǎng)絡(luò)爬蟲之后跛锌,幫人爬了些網(wǎng)頁數(shù)據(jù)贱呐,感覺自己胸前的紅領(lǐng)巾又更鮮艷了一些

最開始用的是BeautifulSoup爬取靜態(tài)網(wǎng)頁丧诺,效果已經(jīng)很讓我驚艷了

后來遇到動(dòng)態(tài)網(wǎng)站,又用了下Selenium奄薇,調(diào)用firefox爬取動(dòng)態(tài)數(shù)據(jù),也是成就感滿滿

然而聽說爬蟲框架Scrapy更高效(B格更高)抗愁,于是決定今天開始學(xué)習(xí)一下

首先聽說windows系統(tǒng)下Scrapy安裝非常的復(fù)雜馁蒂,我已經(jīng)準(zhǔn)備好又折騰一整天,不過有了Anaconda平臺(tái)蜘腌,這些都不是事沫屡,一行代碼搞定:

conda intall scrapy

然后是測試:

創(chuàng)建項(xiàng)目 scrapy startproject test

進(jìn)入項(xiàng)目目錄 cd test

生成爬蟲 scrapy genspider baidu www.baidu.com

爬取百度 scrapy crawl baidu

成功,撒花慶祝撮珠!

(二)——熟悉Xpath

開始Xpath之前先補(bǔ)充一下剛剛踩的一個(gè)小小坑

準(zhǔn)備寫這篇筆記之前打算在筆記本上也裝上scrapy沮脖,結(jié)果用conda install安裝好慢好慢好慢,一度以為是家里網(wǎng)絡(luò)問題芯急,查了下才發(fā)現(xiàn)添加下國內(nèi)鏡像源就可以了勺届,輸入以下代碼即可:

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/

conda config --set show_channel_urls yes

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/msys2/

好了,開始Xpath娶耍,Xpath就是用來在XML文檔中查找目標(biāo)元素的語言免姿,HTML和XML一樣,也是洋蔥一樣的一層一層包裹的結(jié)構(gòu)榕酒,所以可以用Xpath很方便地在HTML文檔中找到我們想要的元素

Xpath長這樣:

//*[@id="t1"]/tbody/tr/td/table/tbody/tr/td/table[1]/tbody/tr[2]/td[2]/table[1]/tbody/tr[2]/td[3]/b

就是一層一層地找下來胚膊,找到目標(biāo)元素

很多瀏覽器都可以很方便地查看網(wǎng)頁中某元素的Xpath,右鍵單擊要查看的目標(biāo)想鹰,選擇“查看元素”紊婉,在顯示的元素源代碼中右鍵選擇“復(fù)制Xpath”,上面一段長長的Xpath就是這么來的

不過實(shí)際使用中不建議直接用上面這樣的Xpath辑舷,因?yàn)檫@個(gè)路徑太長喻犁,還有很多按數(shù)字順序選擇的元素,萬一網(wǎng)頁結(jié)構(gòu)稍有變化(比如彈出個(gè)廣告框)惩妇,這個(gè)結(jié)果就謬之千里了

比較穩(wěn)妥的做法是用id來選擇

嗯株汉,Xpath的語法有很多很多,參加教程吧http://www.w3school.com.cn/xpath/xpath_syntax.asp

接下來就是在scrapy中嘗試一下Xpath的威力

在Anaconda端口輸入scrapy shell www.目標(biāo)網(wǎng)頁.com?

居然又報(bào)錯(cuò)8柩辍(真是一臺(tái)電腦一個(gè)環(huán)境乔妈,各種報(bào)錯(cuò)層出不窮啊)

錯(cuò)誤信息:DLL load failed: 操作系統(tǒng)無法運(yùn)行1%

解決方法:pip install -I cryptography

好啦氓皱,網(wǎng)頁讀取正常啦路召,接下來就用

response.xpath(' ').extract()各種嘗試吧

最后ctrl+d退出

收工睡覺勃刨!

(三)——?jiǎng)?chuàng)建項(xiàng)目

下面要正式開始創(chuàng)建項(xiàng)目了,其實(shí)在第一篇筆記的安裝測試中股淡,就已經(jīng)創(chuàng)建了一個(gè)項(xiàng)目

這次我?計(jì)劃從一些期刊中爬取標(biāo)題身隐、摘要、關(guān)鍵詞等內(nèi)容唯灵,所以我創(chuàng)建了一個(gè)名為articles的項(xiàng)目:

anaconda端口中cd到準(zhǔn)備存儲(chǔ)項(xiàng)目的文件夾贾铝,輸入scrapy startproject articles?

發(fā)現(xiàn)文件夾中多了一個(gè)名為articles的文件夾,點(diǎn)開?是這樣的:

創(chuàng)建articles項(xiàng)目文件夾

?只用一行代碼埠帕,項(xiàng)目就搭好了垢揩,接下來就要往文件夾里面一點(diǎn)一點(diǎn)填東西

這下理解了為什么scrapy叫爬蟲框架,就是人家搭好了架子敛瓷,按照模板填東西就好

(1)定義Item

打開文件夾中的items.py文件叁巨,按照給出的示例(name = scrapy.Field()),定義我準(zhǔn)備爬取的字段呐籽,包括中英文標(biāo)題锋勺、關(guān)鍵詞、摘要等

定義字段列表

?

(2)編寫爬蟲

scrapy提供了不同的爬蟲模板狡蝶,用scrapy genspider -l查看庶橱,有basic、crawl牢酵、csvfeed悬包、xmlfeed四種

先用basic模板試試,輸入scrapy genspider basic web

spiders文件夾中多了一個(gè)basic.py文件

打開編輯一下

basic模板

?start_urls = [' ']里面填入要爬取的文章網(wǎng)頁

def parse(self, response):里面填入網(wǎng)頁中要獲取的字段內(nèi)容馍乙,這里Xpath就大派用場了

用Xpath獲取網(wǎng)頁中的目標(biāo)元素

?(3)運(yùn)行爬蟲

Anaconda端口輸入scrapy crawl basic

編輯好的basic.py爬蟲就開始運(yùn)行了布近,控制臺(tái)輸出了我要的標(biāo)題、關(guān)鍵詞丝格、摘要等內(nèi)容

運(yùn)行爬蟲 控制臺(tái)輸出日志

?換一個(gè)文章網(wǎng)頁也可以

scrapy parse --spider=basic http://另一篇文章的網(wǎng)站.com

(4)填充Item

目前為止撑瞧,第一步定義的Item似乎還沒有發(fā)揮作用,爬取的目標(biāo)元素直接在控制臺(tái)中輸出了显蝌,看起來亂的很

不急预伺,這就把結(jié)果導(dǎo)入到之前定義的Item中

還是編輯basic.py

首先導(dǎo)入編寫的ArcticlesItem:from articles.items import ArticlesItem

定義一個(gè)item實(shí)例:item=ArticlesItem()

給item的字段賦值,如:item['title_CN']=response.xpath('//h3[@class="abs-tit"][1]/text()').extract()

最后不要忘記 return item

定義item并給其字段賦值

?然后端口再運(yùn)行:scrapy crawl basic -o items.xml

結(jié)果直接導(dǎo)出到xml文件(json曼尊、jl酬诀、csv文件都可以,這里我選了xml)

結(jié)果導(dǎo)出到xml文件

?

好了骆撇,大功告成瞒御,一個(gè)最最基礎(chǔ)的爬蟲就搭起來了,后面再接著完善

(四)——清洗Item

上一篇筆記里已經(jīng)成功爬出了需要的字段神郊,但是結(jié)果還不是很理想肴裙,比如還有一些惱人的逗號(hào)趾唱、不必要的分段等等

我以前的解決方式是導(dǎo)出來之后,另外用re模塊進(jìn)行文本處理

但是scrapy框架里面蜻懦,這一步工作也為我們考慮到了甜癞,這就是ItemLoader,相當(dāng)于一個(gè)中轉(zhuǎn)站宛乃,爬下來的數(shù)據(jù)先不著急放到Item里面悠咱,而是在ItemLoader中先清洗一下,然后再導(dǎo)出到Item中

ItemLoader的具體用法見官方文檔:

https://doc.scrapy.org/en/latest/topics/loaders.html

還有一篇中文的博客文章也不錯(cuò):

https://blog.csdn.net/zwq912318834/article/details/79530828

用ItemLoader可以自己構(gòu)建處理器(Processor)烤惊,將爬取的原始數(shù)據(jù)經(jīng)過處理器處理后再導(dǎo)出到Item中乔煞。不過我目前只需要用到內(nèi)置的一些處理器,一個(gè)是Join()柒室,將獲取的多個(gè)段落連接成一個(gè);

還有一個(gè)是MapCompose()逗宜,()里面可以放入多個(gè)函數(shù)雄右,數(shù)據(jù)由第一個(gè)函數(shù)處理完后,傳遞給第二個(gè)函數(shù)纺讲,以此類推擂仍。我只用了一個(gè)函數(shù),MapCompose(lambda i:i.replace(',',''))熬甚,將多余的‘逢渔,’去掉。

好了乡括,現(xiàn)在接著來修改basic.py文件:

首先導(dǎo)入需要的對(duì)象肃廓、函數(shù):

from scrapy.loader import ItemLoader

from scrapy.loader.processors import MapCompose,Join

然后將parse函數(shù)修改如下

使用ItemLoader清洗Item

?導(dǎo)出結(jié)果如圖,比之前舒服多了:

導(dǎo)出結(jié)果

(五)——爬取多個(gè)url

之前的筆記一直只是在拿一個(gè)網(wǎng)頁做試驗(yàn)诲泌,?但實(shí)際上我們需要對(duì)整個(gè)網(wǎng)站進(jìn)行爬取

還是要對(duì)basic.py進(jìn)行修改

最直接的方法就是在start_urls的列表里面添加網(wǎng)頁地址

start_urls = ['url1','url2','url3']

很明顯這不是一個(gè)理智的做法

還有一種方法是如果已經(jīng)有了一個(gè)待爬取網(wǎng)頁的列表盲赊,把它存在txt文檔中,一行為一個(gè)網(wǎng)址敷扫,然后讀取這個(gè)txt文件

start_urls = [i.strip() for i in open('list.txt').readlines()]

這個(gè)方法看著B格也不是很高哀蘑,不過有時(shí)候能應(yīng)急,我在不會(huì)爬取動(dòng)態(tài)網(wǎng)站的時(shí)候就用了這個(gè)方法葵第,把網(wǎng)址索引頁的表格整個(gè)復(fù)制粘貼到excel中绘迁,就這樣弄到了整個(gè)網(wǎng)站的url列表(雖然B格不高,但是夠快夠輕松白涿堋)

現(xiàn)在看看scrapy用的方法吧

先導(dǎo)入需要的函數(shù) from scrapy.http import Request

起點(diǎn)設(shè)置成第一期的網(wǎng)頁start_urls = ['/*the first volume*/']

把原先的parse()函數(shù)更改為parse_item()

再寫一個(gè)新的parse()函數(shù)缀台,這個(gè)函數(shù)一方面調(diào)取下一期的url(next_selector),接著進(jìn)行解析栅受;另一方面調(diào)取本期文章的url(item_selector)将硝,填充item

遍歷整個(gè)網(wǎng)站的parse函數(shù)

?最后端口運(yùn)行scrapy crawl basic -o items.xml

喝幾口茶恭朗,ok,全部爬完啦依疼,一個(gè)10M的xml文件呈現(xiàn)在面前

好吧痰腮,真實(shí)場景是我又遇到了坑

1.Request()中必須加上dont_filter=True,否則什么都爬不到律罢,原因不明(目標(biāo)url和allowed_domains也并不沖突啊膀值。。误辑。沧踏。。巾钉。)

2.原本是用urlparse來解析抽取的相對(duì)路徑翘狱,總是報(bào)錯(cuò),最后只好用了個(gè)字符串替換解決了(還是原因不明)

3.scrapy還提供了一種B格更高的類LinkExtractor砰苍,上面的7行代碼可以用2行解決潦匈,嘗試了一下午,沒有成功

目前就先到這里吧赚导,接下來還準(zhǔn)備再爬一些期刊茬缩,多多準(zhǔn)備語料

scrapy還有更多更強(qiáng)大的功能,留著有空再慢慢研究

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末吼旧,一起剝皮案震驚了整個(gè)濱河市凰锡,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌圈暗,老刑警劉巖掂为,帶你破解...
    沈念sama閱讀 217,542評(píng)論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異厂置,居然都是意外死亡菩掏,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門昵济,熙熙樓的掌柜王于貴愁眉苦臉地迎上來智绸,“玉大人,你說我怎么就攤上這事访忿∏评酰” “怎么了?”我有些...
    開封第一講書人閱讀 163,912評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵海铆,是天一觀的道長迹恐。 經(jīng)常有香客問我,道長卧斟,這世上最難降的妖魔是什么殴边? 我笑而不...
    開封第一講書人閱讀 58,449評(píng)論 1 293
  • 正文 為了忘掉前任憎茂,我火速辦了婚禮,結(jié)果婚禮上锤岸,老公的妹妹穿的比我還像新娘竖幔。我一直安慰自己,他們只是感情好是偷,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,500評(píng)論 6 392
  • 文/花漫 我一把揭開白布拳氢。 她就那樣靜靜地躺著,像睡著了一般蛋铆。 火紅的嫁衣襯著肌膚如雪馋评。 梳的紋絲不亂的頭發(fā)上弧岳,一...
    開封第一講書人閱讀 51,370評(píng)論 1 302
  • 那天徘公,我揣著相機(jī)與錄音,去河邊找鬼孩哑。 笑死玛瘸,一個(gè)胖子當(dāng)著我的面吹牛磕秤,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播捧韵,決...
    沈念sama閱讀 40,193評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼汉操!你這毒婦竟也來了再来?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,074評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤磷瘤,失蹤者是張志新(化名)和其女友劉穎芒篷,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體采缚,經(jīng)...
    沈念sama閱讀 45,505評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡针炉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,722評(píng)論 3 335
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了扳抽。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片篡帕。...
    茶點(diǎn)故事閱讀 39,841評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖贸呢,靈堂內(nèi)的尸體忽然破棺而出镰烧,到底是詐尸還是另有隱情,我是刑警寧澤楞陷,帶...
    沈念sama閱讀 35,569評(píng)論 5 345
  • 正文 年R本政府宣布怔鳖,位于F島的核電站,受9級(jí)特大地震影響固蛾,放射性物質(zhì)發(fā)生泄漏结执。R本人自食惡果不足惜度陆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,168評(píng)論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望献幔。 院中可真熱鬧懂傀,春花似錦、人聲如沸斜姥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽铸敏。三九已至缚忧,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間杈笔,已是汗流浹背闪水。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蒙具,地道東北人球榆。 一個(gè)月前我還...
    沈念sama閱讀 47,962評(píng)論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像禁筏,于是被迫代替她去往敵國和親持钉。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,781評(píng)論 2 354