keywords:python scrapy crawl mysql git 建材 爬蟲(chóng)
之前爬取過(guò)指定建材網(wǎng)站的指定內(nèi)容砸泛,調(diào)研分析采用scrapy框架來(lái)做:框架簡(jiǎn)單阅畴,功能強(qiáng)大棒坏。 scrapy中文官網(wǎng) http://scrapy-chs.readthedocs.io/zh_CN/latest/
寫的scrapy代碼爬取大概1億條數(shù)據(jù),特別是對(duì)于淘寶或者大眾點(diǎn)評(píng)這類的數(shù)據(jù)量很大,前前后后大概花了一個(gè)月的業(yè)余時(shí)間(羽毛球沒(méi)敢丟下)檩禾。爬取建材網(wǎng)站代碼github地址https://github.com/junfeng-feng/Spider.git
首先要分析需求旺入,要那些數(shù)據(jù)兑凿,get/post分頁(yè)分類獲取,其次防止被ban茵瘾,最后數(shù)據(jù)交付礼华。
分析網(wǎng)站
分析網(wǎng)站,最常用的就是使用firefox或者chrome拗秘,F(xiàn)12查看網(wǎng)頁(yè)源代碼圣絮,然后F5刷新頁(yè)面,查看有哪些網(wǎng)絡(luò)(network)請(qǐng)求雕旨,請(qǐng)求的類型及內(nèi)容扮匠。
最多使用的就是翻頁(yè)數(shù)據(jù)的請(qǐng)求捧请,一部分是通過(guò)get請(qǐng)求的url帶上類似PageNo的參數(shù),另外一個(gè)部分就是通過(guò)post json棒搜,json的數(shù)據(jù)含有PageNo類似的字段疹蛉。
抓取網(wǎng)站
scrapy可深度優(yōu)先,或者廣度優(yōu)先力麸,且自帶去重功能可款,自帶過(guò)濾域名等等強(qiáng)大的功能。
由于我們想要抓取的數(shù)據(jù)都是指定的克蚂,比如http://ask.jia.com/裝修問(wèn)答網(wǎng)站中筑舅,問(wèn)答的題目,問(wèn)題描述陨舱,問(wèn)題圖片翠拣;回答的圖片,最佳回答游盲,回答的時(shí)間等等需求方指定的要素误墓。所以我們爬取過(guò)程中,不能采用通用爬蟲(chóng)益缎。
實(shí)際的爬取做法谜慌,簡(jiǎn)單粗暴:分析對(duì)應(yīng)問(wèn)答的頁(yè)面,預(yù)估數(shù)據(jù)數(shù)量莺奔,指定所有的url欣范。比如http://ask.jia.com/a-1006161.html其中,1006161是問(wèn)答的id令哟,我們的做法就是遍歷所有的id恼琼,具體id范圍1-200000000,來(lái)抓取問(wèn)答詳情頁(yè)面屏富。代碼樣例:
start_urls = [] #scrapy的起始url
for id in xrange(1, 2000000):#todo
? ? start_urls.append("http://ask.jia.com/a-%s.html" % id)
分析具體的頁(yè)面
以http://ask.jia.com/a-1006161.html為例晴竞,獲取問(wèn)題的標(biāo)題。
使用item["question_title"]="".join(select.css(".timu_text").xpath(".//h1/text()").extract()).strip()狠半,其中item是scrapy中簡(jiǎn)單的容器噩死,定義pipeline中的數(shù)據(jù)項(xiàng)。解析html使用Selector神年,解析html有很多種比如lxml或者BeautifulSoap等已维,但是scrapy使用自己的一條機(jī)制Selector簡(jiǎn)單高效。詳細(xì)的語(yǔ)法可以參考scrapy文檔已日。
最方便的工具是scrapy shell垛耳,可以在終端打開(kāi)scrapy shell,然后在命令行,一個(gè)個(gè)字段來(lái)調(diào)試分析艾扮。不用每次都啟動(dòng)scrapy crawl來(lái)跑完程序驗(yàn)證抓取的字段是否正確既琴。在shell中一個(gè)個(gè)調(diào)試select.css去的是否正確。(分析具體頁(yè)面需要注意:1.頁(yè)面可能存在特殊性泡嘴,所以需要找多個(gè)頁(yè)面先對(duì)比 2.需要處理沒(méi)有字段的異常情況甫恩,對(duì)于空字段置為空即可)
多級(jí)請(qǐng)求
抓取網(wǎng)站具體內(nèi)容,會(huì)遇到一個(gè)問(wèn)題:一條完整的數(shù)據(jù)酌予,需要多個(gè)網(wǎng)絡(luò)請(qǐng)求get/post按照順序一個(gè)個(gè)來(lái)收集磺箕。
這時(shí)scrapy中的request=Request(brandUrl,callback=self.brandJsonCallBack,priority=1234567)再yieldrequest,在callback中收集數(shù)據(jù)持久化數(shù)據(jù)抛虫,是再合適不過(guò)松靡。樣例請(qǐng)參考github中的tmall代碼。
存儲(chǔ)圖片
scrapy存儲(chǔ)圖片比較簡(jiǎn)單建椰,在setting.py配置 pipeline添加'scrapy.pipelines.images.ImagesPipeline': 1雕欺,同時(shí)配置IMAGES_STORE=r'./img'存儲(chǔ)圖片位置,然后在spider解析頁(yè)面拿到要下載圖片的url添加到item["image_urls"],scrapy就下載圖片棉姐,同時(shí)保存圖片的id在item中屠列,其它請(qǐng)參考scapy文檔。
持久化數(shù)據(jù)
使用twisted和MysqlDb伞矩,在pipeline.py中將item插入數(shù)據(jù)庫(kù)笛洛。其中數(shù)據(jù)庫(kù)鏈接相關(guān)信息配置在settings.py
防止被ban
最有效的方式是設(shè)置下載延遲DOWNLOAD_DELAY=0.1,同時(shí)禁用cookie乃坤。
其它比如設(shè)置user-agent苛让,比如使用TOR,或者使用IP池湿诊,都不怎么好使狱杰。想要防止被禁的其它方法請(qǐng)自行g(shù)oogle。
數(shù)據(jù)清洗
抓取到數(shù)據(jù)后需要做一些處理枫吧,因?yàn)槲覀冏ト〉亩际翘囟ǖ膬?nèi)容浦旱,基本沒(méi)有特別的處理宇色。
Python基礎(chǔ)安裝使用
推薦使用Python 27九杂,不推薦Python3
python 非root安裝:./configure [--prefix=newpath](自己指定安裝路徑) && make && make install
setuptools 安裝
pip install:pip是Python安裝第三方包最方便的工具,會(huì)自動(dòng)下載依賴
pip 國(guó)內(nèi)鏡像:pip install -ihttps://pypi.douban.com/simple/
pip 使用代理: pip --proxy=http://127.0.0.1:2048
pip 安裝包到指定目錄: pip install --install-option="--prefix=$PREFIX_PATH" package_name
python 字符編碼處理 print file file.write請(qǐng)參考http://www.reibang.com/p/53bb448fe85b