快一年沒更新博客了,現在總結一下這大半年來研究、學習的知識,博客陸續更新中。。。
這個爬蟲項目是去年4、5月份做的,主要技術是BeautifulSoup、select、requests、MongoDB、highchart
首先,我們登陸趕集網可以看到二手商品信息的首頁,即爬蟲的起始url是:http://sh.ganji.com/wu/,分析網頁結構可以看到二手商品信息分類中有:手機、手機配件、手機號碼、筆記本電腦、台式機等20多個商品分類子頻道,分別打開每個子頻道的url,可以看到對應的二手商品列表,每個二手商品列表中的url對應一個詳細頁面,我們要獲取的就是每個詳細頁面上的信息。
首先,我們定義 headers 部分,headers 包含 User-Agent、Cookie、Referer等信息,這是為了偽裝成瀏覽器的形式,以應對反爬蟲措施。
requests.get解析url:
wb_data = requests.get(url, headers=headers)
BeautifulSoup的lxml解析文本:
soup = BeautifulSoup(wb_data.text, 'lxml')
關於BeautifulSoup中的各種html解析器,我做了一個小的研究,html.parser:這是python自帶的,速度上當然是沒問題的,但是兼容性不好, python2.7.3以前的版本不兼容;lxml:解析速度很快、兼容性好,但是正因為其解析速度快,有時會出現解析不到數據的情況;html5lib:兼容性非常好,解析成功率非常高(有時用lxml解析不到時,用html5lib卻能解析到),但是速度非常慢;綜合這三種html解析器,我覺得lxml是最為折中的。
select選擇器定位文本:
links = soup.select('div.main-pop dl dt a')
獲取詳細信息:
data = { 'title': soup.title.text.strip(), 'price': soup.select('i.f22.fc-orange.f-type')[0].text, 'area': list(map(lambda x: x.text.strip(), soup.select('ul.det-infor li:nth-of-type(3) a')[1:])), 'fdate': soup.select('i.pr-5')[0].text.strip()[:-3], 'cates': list(map(lambda x: x.text, soup.select('div.crumbs.routes.clearfix a'))),
'url': url }
把詳細信息存儲到字典data中,然后將data插入到mongodb數據庫中
斷點續傳去重:
在持續爬取的過程中,往往會遇到網絡中斷、ip被封、斷電等等的情況,為確保在網絡恢復正常時爬蟲能夠繼續生效,引入斷點續傳:
db_urls = [item['url'] for item in ganji_url_list.find()] index_urls = [item['url'] for item in ganji_info.find()] x = set(db_urls) y = set(index_urls) rest_of_urls = x - y
由於我們是根據每個url爬取其詳細信息的,首先把url爬取到數據庫中,然后從數據庫中查找詳細信息中的url(已經爬取的),與總的url做差,得到未爬取的url,當前從未爬取的url開始,這樣可以保證爬取的信息不會是重復的
最后,總結下爬取趕集網遇到的反爬措施:
1、直接暴力爬取(很多網頁解析不到數據)
2、偽裝成瀏覽器進行爬取,並設置延時(爬一段時間后發現IP被封)
3、偽裝成瀏覽器、使用隨機代理IP、設置隨機延時(爬幾天之后發現會彈出輸入驗證碼的對話框),但是它的反爬措施仍不夠完善,當出現驗證碼時,反復地多請求幾次,驗證碼就不會出現了
爬蟲部分代碼詳見github:https://github.com/a342058040/reptile_ganjiwang.git