把以前寫的爬蟲代碼整理成教程,方便以后查閱讥巡,可以爬點(diǎn)感興趣的東西玩一玩篙梢。
1.運(yùn)行環(huán)境及安裝:
1.運(yùn)行環(huán)境
默認(rèn)讀者已經(jīng)掌握了python2/3的基本操作厉颤。
??操作系統(tǒng):win7
??IDE:Anaconda3 (32-bit)中的jupyter notebook(Anaconda3中對應(yīng)的是python3,用python2也無妨怀大,推薦用python3)
??用到的python庫:BeautifulSoup(一個可以從HTML或XML中提取數(shù)據(jù)的python庫)纱兑,requests(rllib的升級版,打包了全部功能并簡化了使用方法)
??瀏覽器:Google Chrome
2.Anaconda3 安裝
Anaconda是一個用于科學(xué)計算的Python發(fā)行版叉寂,支持 Linux, Mac, Windows系統(tǒng)萍启,提供了包管理與環(huán)境管理的功能,可以很方便地解決多版本python并存屏鳍、切換以及各種第三方包安裝問題勘纯。
??登陸Anaconda官網(wǎng)下載相應(yīng)版本并安裝:https://www.continuum.io/downloads/
??常用的庫numpy,pandas等都集成在了Anaconda里,本教程用的BeautifulSoup也包含在內(nèi)钓瞭。
??安裝完成后驳遵,點(diǎn)擊開始菜單,找到Anaconda文件夾中的jupyter notebook山涡,打開堤结。
??jupyter notebook是一個在瀏覽器中運(yùn)行的IDE,訪問本地文件鸭丛。當(dāng)然竞穷,用其他的IDE也可以,這里推薦用notebook鳞溉。
??5分鐘可快速入門notebook瘾带,簡明教程請移步http://codingpy.com/article/getting-started-with-jupyter-notebook-part-1/。
??開搞熟菲!
2.爬取網(wǎng)頁中鏈接對應(yīng)的網(wǎng)址
我們要爬取的內(nèi)容為趕集網(wǎng)二手手機(jī)交易頁面中每個商品的詳細(xì)信息看政,網(wǎng)址為:http://bj.ganji.com/shouji/a2/朴恳。
??我們的思路是這樣的:首先獲得每個商品對應(yīng)的鏈接,然后進(jìn)入這個鏈接允蚣,爬取商品信息于颖。
1.解析網(wǎng)頁元素
因?yàn)槲覀円@得圖1中每個商品的鏈接,需要解析網(wǎng)頁元素嚷兔。因?yàn)槭侨腴T教程森渐,所以不會涉獵太多HTML的知識。
??對著圖1中第1個商品“蘋果三星華為……”右擊冒晰,選擇“檢查”章母,在瀏覽器右側(cè)會彈出圖2所示的窗口:
紅色箭頭指向的那一行表示層級關(guān)系,從開始的html字段開始翩剪,一直定位到a.ft-tit字段乳怎,最終定位到商品所在的網(wǎng)頁源碼的位置,即我們想要找的元素前弯。參考這個層級關(guān)系蚪缀,我們可以自己定位任意想要的元素(編程時會用到)。
??例如恕出,現(xiàn)在要手動定位第1個商品:
??1. 點(diǎn)擊圖2任意空白部分(保證該窗口為當(dāng)前活動窗口)询枚,按下鍵盤上的Ctrl+F,會在圖2中的側(cè)邊欄的中間部分彈出一個搜索框浙巫,如藍(lán)色箭頭所指金蜀。
??2. 在搜索框中輸入紅色箭頭所指的層級字段,中間以“>”相連的畴,即:html>body>#wrapper>div>div>dl>dd.feature>div.ft-db>ul>li.js-item>a.ft-tit
渊抄。第1個商品所在字段自動加上了底紋。
??3. 搜索框右側(cè)的“1 of 70”表示與此定位同級的位置一共有70個丧裁,現(xiàn)在是第1個护桦,也就我們要定位的第1個商品〖褰浚可以通過搜索框右側(cè)的上/下箭頭選擇同級的定位二庵,比如下一個商品為“五動全城……”,可見我們定位的字段正是我們想要的缓呛。
??顯然催享,在底紋字段中,我們想要爬取的正是下面這個鏈接:
“http://bj.ganji.com/shouji/29130462136655x.htm
2.提取網(wǎng)頁元素
首先哟绊,引入我們要用到的python庫:
from bs4 import BeautifulSoup
import requests
爬取鏈接:
#目標(biāo)網(wǎng)址
url = 'http://bj.ganji.com/shouji/a2/'
#請求訪問目標(biāo)網(wǎng)址
wb_data = requests.get(url)
#用lxml解析目標(biāo)網(wǎng)址
soup = BeautifulSoup(wb_data.text,'lxml')
#定位到我們要爬取的信息因妙,返回一個列表(注意每個“>”前后都有空格)
links = soup.select('html > body > #wrapper > div > div > dl > dd.feature > div.ft-db > ul > li.js-item > a.ft-tit')
#在每個商品的源碼中,篩選出我們想要的鏈接,存放到列表link_list 中
link_list = []
for each_link in links:
link_list.append(each_link.get('href'))
在上面的代碼中兰迫,我們用requests的get方法去訪問目標(biāo)網(wǎng)址,返回數(shù)據(jù)到wb_data中炬称,然后用BeautifulSoup方法用lxml來解析wb_data汁果,以便可以提取我們想要的信息。select方法返回所有滿足定位要求的源碼段到一個列表中玲躯,一共是70個据德,對應(yīng)70個商品。最后對列表中的每個元素應(yīng)用get方法跷车,獲取我們要想的字段棘利。對于如下一般結(jié)構(gòu):
<a href="xxx" target="xxx" class="xxx">華為 三星……</a>
- 如果要獲得href,target和class等屬性字段的值朽缴,可以用get方法善玫。如each_link.get('href'),each_link.get('target')和each_link.get('class')分別以字符串的形式返回href密强,target和class的值茅郎。
- 如果要獲得< a >和< /a >之間的文本,可用get_text方法即each_link.get_text()或渤,返回字符串“華為 三星……”系冗。
這里我們想要href的值,即鏈接薪鹦,故應(yīng)用get方法掌敬,存放到列表link_list中。查看一下link_list中的元素池磁,如圖3奔害。
??我們成功了獲取了每個商品的鏈接,接下來就要依次訪問這些鏈接來爬取商品信息地熄。
3.爬取商品詳細(xì)信息
1.爬取單個商品信息
以第1個商品為例舀武,我們要爬取的內(nèi)容為標(biāo)題、發(fā)布日期离斩、價格和地點(diǎn)银舱,見圖4。
??和上面的過程一樣跛梗,對標(biāo)題右擊寻馏,檢查,得到標(biāo)題的定位(見圖5)核偿。然后重復(fù)同樣的過程诚欠,得到其他信息的定位。
??爬取這些信息:
url = 'http://bj.ganji.com/shouji/29130462136655x.htm'
wb_data = requests.get(url)
soup = BeautifulSoup(wb_data.text,'lxml')
title = soup.select('h1.title-name')[0].get_text()
price = soup.select('i.f22.fc-orange.f-type')[0].get_text()
date = soup.select('i.pr-5')[0].get_text()
areas = soup.select('ul.det-infor > li > a')
area = ''
for i in areas:
area += i.get_text()+'-'
area = area[:-1]
data = {
'標(biāo)題':title,
'日期':date.strip().split('\xa0')[0],
'價格':price,
'地點(diǎn)':area
}
在上面的代碼中,我們訪問第1個商品的鏈接轰绵,解析網(wǎng)頁粉寞,爬取了我們想要的4個信息,然后把這些信息放到一個字典里左腔,這樣每個商品的信息都可以用一個字典來表示唧垦。
??注意到,在前3個select方法中液样,我們只寫了1個字段振亮;在第4個select方法中,我們只寫了3個字段鞭莽。這是因?yàn)榉唤眨谶@個網(wǎng)頁中,只寫這幾個字段就足以唯一定位出我們想要的信息的位置澎怒,無需寫完整褒搔。(讀者可自行驗(yàn)證)當(dāng)然,你想寫全了也無妨喷面。
??打印上面代碼中的data:
{'標(biāo)題': '蘋果7 7P 分期付款可回收手機(jī)以舊換新 - 4200元', '價格': '4200', '地點(diǎn)': ' 北京-海淀'}
這樣站超,單個商品的信息就存放在了一個字典中。
2.爬取所有商品詳細(xì)信息
好了乖酬,現(xiàn)在你已經(jīng)會爬取單個商品了死相,那爬取所有商品也不在話下了。在上面的代碼中加個循環(huán)就能爬取所有商品信息了:
#爬取列表中的每個鏈接對應(yīng)的商品信息
for each_link in link_list:
wb_data = requests.get(each_link)
soup = BeautifulSoup(wb_data.text,'lxml')
#篩選標(biāo)題咬像、價格算撮、日期、位置
title = soup.select('h1.title-name')[0].get_text()
price = soup.select('i.f22.fc-orange.f-type')[0].get_text()
date = soup.select('i.pr-5')[0].get_text()
areas = soup.select('ul.det-infor > li > a')
area = ''
for i in areas:
area += i.get_text()+'-'
area = area[:-1]
data = {
'標(biāo)題':title,
'日期':date.strip().split('\xa0')[0],
'價格':price,
'地點(diǎn)':area
}
print (data)
對于代碼中細(xì)節(jié)的處理县昂,讀者可自行嘗試肮柜。
??輸出如下(只顯示前6條商品信息):
{'標(biāo)題': '‘五動全城’ 分期付款零首付 全新二手手機(jī) 多種購機(jī)方式!!! - 3950元', '日期': '04月26日', '價格': '3950', '地點(diǎn)': ' 北京-海淀'}
{'標(biāo)題': '北京實(shí)體店買手機(jī)《就分期》分期付款最低0首付 - 4488元', '日期': '03月25日', '價格': '4488', '地點(diǎn)': ' 北京'}
{'標(biāo)題': '蘋果iphoe7 7plus 0利息三星手機(jī)分期付款 審核快 通過率高【平價二手】【以舊換新】 - 4188元', '日期': '02月16日', '價格': '4188', '地點(diǎn)': ' 北京'}
{'標(biāo)題': '蘋果7 7P 分期付款可回收手機(jī)以舊換新 - 4200元', '日期': '04月25日', '價格': '4200', '地點(diǎn)': ' 北京-海淀'}
{'標(biāo)題': '有用分期 0首付起( 全系列手機(jī)) 當(dāng)場拿機(jī) 優(yōu)惠288禮包 - 4599元', '日期': '03月07日', '價格': '4599', '地點(diǎn)': ' 北京-朝陽'}
{'標(biāo)題': '《有分期》大型手機(jī)專賣店手機(jī)分期支持0首付 - 4288元', '日期': '04月26日', '價格': '4288', '地點(diǎn)': ' 北京-朝陽'}
至此為止,我們基本掌握了理想條件下爬取網(wǎng)頁的操作倒彰。但以上我們只是爬取了二手手機(jī)交易頁面這一頁的所有商品审洞,注意到下面其實(shí)還有很多頁,如圖6待讳。
??下面我們就來爬取趕集網(wǎng)上所有二手手機(jī)的信息芒澜。
3.爬取趕集網(wǎng)所有二手手機(jī)信息
往下面翻頁,會發(fā)現(xiàn)不同頁的網(wǎng)址是遵循一定規(guī)律的创淡。第1頁到第3頁的網(wǎng)址如下:
http://bj.ganji.com/shouji/a2/
http://bj.ganji.com/shouji/a2o2/
http://bj.ganji.com/shouji/a2o3/
第1頁的網(wǎng)址也可以寫成
http://bj.ganji.com/shouji/a2o1/
也就是說痴晦,第N頁的網(wǎng)址就是
http://bj.ganji.com/shouji/a2oN/
根據(jù)這個規(guī)律,我們就能通過編程來爬取所有商品了琳彩。只需要把爬取商品鏈接的代碼稍作修改即可:
url_base = 'http://bj.ganji.com/shouji/a2o'
N = 2 #要爬取的頁數(shù)
link_list = []
for i in range(N):
url = url_base + str(i+1)
wb_data = requests.get(url)
soup = BeautifulSoup(wb_data.text,'lxml')
links = soup.select('a.ft-tit')
for each_link in links:
link_list.append(each_link.get('href'))
4.最后的話
一般來說誊酌,網(wǎng)站都有反爬蟲技術(shù)部凑,在如此短的時間內(nèi)爬取那么多信息,網(wǎng)站會認(rèn)為你是爬蟲碧浊。關(guān)于“反反爬蟲”也有很多方法涂邀,最簡單也是最笨的一個辦法就是延時,即每爬取幾條信息就延時幾秒箱锐,讓自己的爬蟲看起來是一個正常上網(wǎng)的人比勉。可用python自帶的time模塊來完成瑞躺,讀者可自行嘗試。
??像趕集網(wǎng)兴想、58同城幢哨、豆瓣還是比較好爬的,數(shù)據(jù)比較規(guī)整嫂便。讀者可以去一些小網(wǎng)站試試捞镰,可能需要你對數(shù)據(jù)作更多細(xì)節(jié)上的處理。
好了毙替,現(xiàn)在你已經(jīng)學(xué)會爬蟲的基本操作了岸售,可以去其他網(wǎng)站爬取一些感興趣的東西下載下來,比如說煎蛋網(wǎng)