1.scrapy安裝
之前安裝過pip勒叠,所以直接輸入 pip install scrapy 就行了识颊,會(huì)自動(dòng)下載好所有需要的組件的
2.創(chuàng)建scrapy項(xiàng)目
scrapy startproject scrapyspider
該命令會(huì)自動(dòng)在當(dāng)前文件夾下創(chuàng)建scrapyspider的目錄
3.啟動(dòng)爬蟲命令
scrapy crawl yourspidername
如果后面跟 -o filename.csv 就可以把爬取到的內(nèi)容以csv格式保存起來
4.爬蟲編寫
需求:想學(xué)爬蟲的目標(biāo)是自動(dòng)去某個(gè)小黃網(wǎng)上搜索最近新出的電影填帽,拿到電影番號(hào)评也,名稱瞳脓,類別等信息悔政,再用番號(hào)去bt站點(diǎn)搜索有沒有該資源,如果有桥言,再去保存電影的磁力鏈接萌踱,最后保存成csv文件
在實(shí)踐的過程中遇到了一些非常坑爹的問題号阿,一一記錄下來并鸵,供參考
1)scrapy教學(xué)中的那個(gè)網(wǎng)站已經(jīng)不在了。扔涧。园担。
2)爬取目標(biāo)網(wǎng)站(小黃網(wǎng))的時(shí)候届谈,報(bào)403的錯(cuò)誤,也就是禁止訪問弯汰。這個(gè)問題很常見艰山,在網(wǎng)上查了一下,說是切換一個(gè)user-agent就行了咏闪。然而坑爹的地方來了曙搬,都沒有說怎么去自定義headers。有人說在設(shè)置里設(shè)置一下就行了鸽嫂,然后配的圖是寫在scrapy.cfg里的纵装,我被嚴(yán)重誤導(dǎo)了,以為設(shè)置的東西都要寫在這里据某,結(jié)果怎么都不行橡娄。實(shí)際上是應(yīng)該寫在setting.py中。
還有另外一種方法癣籽,就是寫在爬蟲內(nèi)挽唉,然后在調(diào)用請(qǐng)求的時(shí)候,把headers替換成你寫的就行了
如下
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36"
}
headers里不止可以寫user-agent才避,還可以寫很多橱夭,具體可以寫什么,可以打開瀏覽器的F12桑逝,在請(qǐng)求里看一下平時(shí)上網(wǎng)瀏覽網(wǎng)頁headers都發(fā)送了哪些信息棘劣。
也可以寫不同的headers以應(yīng)對(duì)不同網(wǎng)頁的要求
調(diào)用的時(shí)候
yield Request(url, headers = self.headers)
這樣就可以替換掉headers了
換掉了headers之后,成功訪問了網(wǎng)站楞遏,并拿到了想要的網(wǎng)頁
3)字符編碼的問題
拿到番號(hào)和電影名稱后茬暇,迫不及待打開csv文件,結(jié)果一看全是亂碼寡喝。我想到這應(yīng)該是字符編碼的問題糙俗。網(wǎng)上查了下說是要以u(píng)tf-8編碼,結(jié)果試了不行预鬓。后來想到電影名稱都是日文巧骚,應(yīng)該用gbk編碼,試了下果然成功了
于是重新啟動(dòng)爬蟲格二,結(jié)果在爬到第三頁的時(shí)候劈彪,報(bào)錯(cuò)了。查了下是因?yàn)樽址幋a的問題顶猜,日文中有些符號(hào)沧奴,沒法用gbk編碼,但是encode方法长窄,可以追加一個(gè)“replace”參數(shù)滔吠,將無法編碼的符號(hào)用纲菌?代替,或者用“ignore”疮绷,忽視無法編碼的特殊符號(hào)翰舌。
添加參數(shù)后,成功爬了十頁(我控制只爬10頁)矗愧,示例:
item['title'] = movie.xpath('.//div[@class="photo-info"]/span/text()').extract()[0].encode('GBK','replace')
4)xpath的學(xué)習(xí)
xpath非常簡(jiǎn)單灶芝,也很強(qiáng)大郑原,借助xpath可以很快定位到想要的內(nèi)容唉韭,看10分鐘差不多就可以掌握了
5)從一個(gè)網(wǎng)頁獲得item如何將其作為參數(shù)傳遞到另一個(gè)請(qǐng)求中
這個(gè)問題困擾了我很久。我一開始想的很簡(jiǎn)單犯犁。我首先在一個(gè)循環(huán)里獲得了該頁面里所有電影title属愤,番號(hào),和對(duì)應(yīng)的下一級(jí)頁面的鏈接酸役,于是我想當(dāng)然的直接在該循環(huán)里request那個(gè)鏈接
yield item
item['movie_detail'] = movie.xpath('.//a/@href').extract()
request = Request(url=item['movie_detail'][0],callback=self.parse_detail, headers=self.headers)
yield request
這是我一開始寫的代碼住诸,上面那個(gè)yield item是保存之前的電影titile之類信息的
然而運(yùn)行了之后出現(xiàn)了很多錯(cuò)誤,得不到想要的結(jié)果
對(duì)了這里還得提一句涣澡,Request請(qǐng)求里贱呐,可以填寫callback來決定返回的數(shù)據(jù)由誰來處理,不同結(jié)構(gòu)的頁面肯定要不同的方法來處理
我陷入了無盡的麻煩當(dāng)中入桂,先是查了yield到底是怎么處理函數(shù)的奄薇,后來了解到y(tǒng)ield Request是異步的,所以我實(shí)際上傳進(jìn)函數(shù)的是循環(huán)到最后一次movie_detail[0]
后來又研究到底把yeild放在哪里抗愁,然而放在哪里都不對(duì)馁蒂。
此間網(wǎng)上查了很多,又得知蜘腌,想要傳遞數(shù)據(jù)沫屡,可以用Request里的meta參數(shù)。然而很多人就說了這么一句話撮珠,沒有例子沮脖,也沒有詳細(xì)展開說,具體要怎么用芯急,像我這樣的小白真是頭都大了勺届。后來在stackoverflow上找到一個(gè)好心人寫的一個(gè)詳細(xì)的例子,一下子點(diǎn)開了我志于。
item['movie_detail'] = movie.xpath('.//a/@href').extract()
request = Request(url=item['movie_detail'][0],callback=self.parse_detail, headers=self.headers)
request.meta['item_1'] = item
yield request
像這樣可以把item通過meta傳遞給請(qǐng)求涮因,同時(shí)在處理方法中寫一個(gè)
item_1 = response.meta['item_1']
來接收參數(shù)。同理伺绽,可以再把item_1傳遞給item_2等等养泡,這樣爬蟲就可以帶著數(shù)據(jù)一級(jí)一級(jí)往下爬了嗜湃,然后正確的把來自不同頁面的數(shù)據(jù)組合在一起
6)反爬蟲
一開始沒注意,也沒限速澜掩,沉浸在爬蟲終于正常工作的狂喜之中购披,結(jié)果被bt站點(diǎn)封了ip(喜聞樂見)
常見的一些措施有,準(zhǔn)備很多個(gè)user-agaent肩榕,爬蟲工作的時(shí)候隨機(jī)切換刚陡;禁止cookie;設(shè)置延遲大一點(diǎn)
這些都在setting.py里株汉,而不是在scrapy.cfg里
暫時(shí)遇到的問題就這些筐乳,當(dāng)然與我研究的爬蟲還很初級(jí)有關(guān)。下次試試爬爬json的網(wǎng)站乔妈。研究爬蟲只是因?yàn)閯倓偪赐暌恍┗A(chǔ)的python的語法蝙云,想找個(gè)東西練練手。在這次的練手過程中收獲還是挺大的路召,果然動(dòng)手才是學(xué)習(xí)語言的最好途徑勃刨。