python爬蟲入門1

把以前寫的爬蟲代碼整理成教程,方便以后查閱,可以爬點感興趣的東西玩一玩。

1.運行環境及安裝:

1.運行環境

默認讀者已經掌握了python2/3的基本操作。
??操作系統:win7
??IDE:Anaconda3 (32-bit)中的jupyter notebook(Anaconda3中對應的是python3,用python2也無妨,推薦用python3)
??用到的python庫:BeautifulSoup(一個可以從HTML或XML中提取數據的python庫),requests(rllib的升級版,打包了全部功能并簡化了使用方法)
??瀏覽器:Google Chrome

2.Anaconda3 安裝

Anaconda是一個用于科學計算的Python發行版,支持 Linux, Mac, Windows系統,提供了包管理與環境管理的功能,可以很方便地解決多版本python并存、切換以及各種第三方包安裝問題。
??登陸Anaconda官網下載相應版本并安裝:https://www.continuum.io/downloads/
??常用的庫numpy,pandas等都集成在了Anaconda里,本教程用的BeautifulSoup也包含在內。
??安裝完成后,點擊開始菜單,找到Anaconda文件夾中的jupyter notebook,打開。
??jupyter notebook是一個在瀏覽器中運行的IDE,訪問本地文件。當然,用其他的IDE也可以,這里推薦用notebook。
??5分鐘可快速入門notebook,簡明教程請移步http://codingpy.com/article/getting-started-with-jupyter-notebook-part-1/
??開搞!

2.爬取網頁中鏈接對應的網址

我們要爬取的內容為趕集網二手手機交易頁面中每個商品的詳細信息,網址為:http://bj.ganji.com/shouji/a2/
??我們的思路是這樣的:首先獲得每個商品對應的鏈接,然后進入這個鏈接,爬取商品信息。

1.解析網頁元素

因為我們要獲得圖1中每個商品的鏈接,需要解析網頁元素。因為是入門教程,所以不會涉獵太多HTML的知識。


圖1

??對著圖1中第1個商品“蘋果三星華為……”右擊,選擇“檢查”,在瀏覽器右側會彈出圖2所示的窗口:

圖2

紅色箭頭指向的那一行表示層級關系,從開始的html字段開始,一直定位到a.ft-tit字段,最終定位到商品所在的網頁源碼的位置,即我們想要找的元素。參考這個層級關系,我們可以自己定位任意想要的元素(編程時會用到)。
??例如,現在要手動定位第1個商品:
??1. 點擊圖2任意空白部分(保證該窗口為當前活動窗口),按下鍵盤上的Ctrl+F,會在圖2中的側邊欄的中間部分彈出一個搜索框,如藍色箭頭所指。
??2. 在搜索框中輸入紅色箭頭所指的層級字段,中間以“>”相連,即:html>body>#wrapper>div>div>dl>dd.feature>div.ft-db>ul>li.js-item>a.ft-tit
。第1個商品所在字段自動加上了底紋。
??3. 搜索框右側的“1 of 70”表示與此定位同級的位置一共有70個,現在是第1個,也就我們要定位的第1個商品。可以通過搜索框右側的上/下箭頭選擇同級的定位,比如下一個商品為“五動全城……”,可見我們定位的字段正是我們想要的。
??顯然,在底紋字段中,我們想要爬取的正是下面這個鏈接:

“http://bj.ganji.com/shouji/29130462136655x.htm

2.提取網頁元素

首先,引入我們要用到的python庫:

from bs4 import BeautifulSoup
import requests

爬取鏈接:

#目標網址
url = 'http://bj.ganji.com/shouji/a2/'  
 #請求訪問目標網址
wb_data = requests.get(url) 
#用lxml解析目標網址
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方法去訪問目標網址,返回數據到wb_data中,然后用BeautifulSoup方法用lxml來解析wb_data,以便可以提取我們想要的信息。select方法返回所有滿足定位要求的源碼段到一個列表中,一共是70個,對應70個商品。最后對列表中的每個元素應用get方法,獲取我們要想的字段。對于如下一般結構:

<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的值,即鏈接,故應用get方法,存放到列表link_list中。查看一下link_list中的元素,如圖3。

圖3

??我們成功了獲取了每個商品的鏈接,接下來就要依次訪問這些鏈接來爬取商品信息。

3.爬取商品詳細信息

1.爬取單個商品信息

以第1個商品為例,我們要爬取的內容為標題、發布日期、價格和地點,見圖4。

圖4

??和上面的過程一樣,對標題右擊,檢查,得到標題的定位(見圖5)。然后重復同樣的過程,得到其他信息的定位。

圖5

??爬取這些信息:

    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 = {
        '標題':title,
        '日期':date.strip().split('\xa0')[0],
        '價格':price,
        '地點':area
    }

在上面的代碼中,我們訪問第1個商品的鏈接,解析網頁,爬取了我們想要的4個信息,然后把這些信息放到一個字典里,這樣每個商品的信息都可以用一個字典來表示。
??注意到,在前3個select方法中,我們只寫了1個字段;在第4個select方法中,我們只寫了3個字段。這是因為,在這個網頁中,只寫這幾個字段就足以唯一定位出我們想要的信息的位置,無需寫完整。(讀者可自行驗證)當然,你想寫全了也無妨。
??打印上面代碼中的data:

{'標題': '蘋果7 7P 分期付款可回收手機以舊換新 - 4200元', '價格': '4200', '地點': ' 北京-海淀'}

這樣,單個商品的信息就存放在了一個字典中。

2.爬取所有商品詳細信息

好了,現在你已經會爬取單個商品了,那爬取所有商品也不在話下了。在上面的代碼中加個循環就能爬取所有商品信息了:

#爬取列表中的每個鏈接對應的商品信息
for each_link in link_list: 
    wb_data = requests.get(each_link)
    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 = {
        '標題':title,
        '日期':date.strip().split('\xa0')[0],
        '價格':price,
        '地點':area
    }
    print (data)

對于代碼中細節的處理,讀者可自行嘗試。
??輸出如下(只顯示前6條商品信息):

{'標題': '‘五動全城’ 分期付款零首付 全新二手手機 多種購機方式!!! - 3950元', '日期': '04月26日', '價格': '3950', '地點': ' 北京-海淀'}
{'標題': '北京實體店買手機《就分期》分期付款最低0首付 - 4488元', '日期': '03月25日', '價格': '4488', '地點': ' 北京'}
{'標題': '蘋果iphoe7 7plus 0利息三星手機分期付款 審核快 通過率高【平價二手】【以舊換新】 - 4188元', '日期': '02月16日', '價格': '4188', '地點': ' 北京'}
{'標題': '蘋果7 7P 分期付款可回收手機以舊換新 - 4200元', '日期': '04月25日', '價格': '4200', '地點': ' 北京-海淀'}
{'標題': '有用分期 0首付起( 全系列手機) 當場拿機 優惠288禮包 - 4599元', '日期': '03月07日', '價格': '4599', '地點': ' 北京-朝陽'}
{'標題': '《有分期》大型手機專賣店手機分期支持0首付 - 4288元', '日期': '04月26日', '價格': '4288', '地點': ' 北京-朝陽'}

至此為止,我們基本掌握了理想條件下爬取網頁的操作。但以上我們只是爬取了二手手機交易頁面這一頁的所有商品,注意到下面其實還有很多頁,如圖6。

圖6

??下面我們就來爬取趕集網上所有二手手機的信息。

3.爬取趕集網所有二手手機信息

往下面翻頁,會發現不同頁的網址是遵循一定規律的。第1頁到第3頁的網址如下:

http://bj.ganji.com/shouji/a2/ 
http://bj.ganji.com/shouji/a2o2/
http://bj.ganji.com/shouji/a2o3/

第1頁的網址也可以寫成

http://bj.ganji.com/shouji/a2o1/

也就是說,第N頁的網址就是

http://bj.ganji.com/shouji/a2oN/

根據這個規律,我們就能通過編程來爬取所有商品了。只需要把爬取商品鏈接的代碼稍作修改即可:

url_base = 'http://bj.ganji.com/shouji/a2o' 
N = 2  #要爬取的頁數
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.最后的話

一般來說,網站都有反爬蟲技術,在如此短的時間內爬取那么多信息,網站會認為你是爬蟲。關于“反反爬蟲”也有很多方法,最簡單也是最笨的一個辦法就是延時,即每爬取幾條信息就延時幾秒,讓自己的爬蟲看起來是一個正常上網的人。可用python自帶的time模塊來完成,讀者可自行嘗試。
??像趕集網、58同城、豆瓣還是比較好爬的,數據比較規整。讀者可以去一些小網站試試,可能需要你對數據作更多細節上的處理。

好了,現在你已經學會爬蟲的基本操作了,可以去其他網站爬取一些感興趣的東西下載下來,比如說煎蛋網

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,825評論 6 546
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,814評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,980評論 0 384
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 64,064評論 1 319
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,779評論 6 414
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 56,109評論 1 330
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,099評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,287評論 0 291
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,799評論 1 338
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,515評論 3 361
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,750評論 1 375
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,221評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,933評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,327評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,667評論 1 296
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,492評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,703評論 2 380

推薦閱讀更多精彩內容

  • 大家好哈,最近博主在學習Python,學習期間也遇到一些問題,獲得了一些經驗,在此將自己的學習系統地整理下來,如果...
    xmsumi閱讀 390評論 0 0
  • 最近閑的無聊,想爬點書看看。 于是我選擇了這個網站雨楓軒。 STEP1.分析網站 一開始我想通過一篇文章引用的鏈接...
    查爾德77閱讀 10,036評論 13 136
  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,808評論 25 708
  • 1 前言 作為一名合格的數據分析師,其完整的技術知識體系必須貫穿數據獲取、數據存儲、數據提取、數據分析、數據挖掘、...
    whenif閱讀 18,102評論 45 523
  • 佛悲憫仙人緣由 不懼身前妖魔鬼 橫刀立馬殺破狼 可悲身后萬千絲 毀身無妨心受寒
    縱情嬉戲天地間閱讀 193評論 0 0