1. 程式人生 > >Python新手寫出漂亮的爬蟲程式碼

Python新手寫出漂亮的爬蟲程式碼

BeautifulSoup神器

Python一個第三方庫bs4中有一個BeautifulSoup庫,是用於解析html程式碼的,換句話說就是可以幫助你更方便的通過標籤定位你需要的資訊。這裡只介紹兩個比較關鍵的方法:

1、find方法和findAll方法:
首先,BeautifulSoup會先將整個html或者你所指定的html程式碼程式設計一個BeautifulSoup物件的例項(不懂物件和例項不要緊,你只要把它當作是一套你使用F12看到的樹形html程式碼程式碼就好),這個例項可以使用很多方法,最常用的就是find和findAll,二者的功能是相同的,通過find( )的引數,即find( )括號中指定的標籤名,屬性名,屬性值去搜索對應的標籤,並獲取它,不過find只獲取搜尋到的第一個標籤,而findAll將會獲取搜尋到的所有符合條件的標籤,放入一個迭代器(實際上是將所有符合條件的標籤放入一個list),findAll常用於兄弟標籤的定位,如剛才定位口碑資訊,口碑都在dl標籤下,而同一頁的10條口碑對應於10個dl標籤,這時候用find方法只能獲取第一個,而findAll會獲取全部的10個標籤,存入一個列表,想要獲取每個標籤的內容,只需對這個列表使用一個for迴圈遍歷一遍即可。

2、get_text()方法:
使用find獲取的內容不僅僅是我們需要的內容,而且包括標籤名、屬性名、屬性值等,比如使用find方法獲取"<Y yy='aaa'>xxxx</Y>" 的內容xxxx,使用find後,我們會得到整個"<Y yy='aaa'>xxxx</Y>",十分冗長,實際我們想要的僅僅是這個標籤的內容xxxx,因此,對使用find方法後的物件再使用get_text( )方法,就可以得到標籤的內容了,對應到這裡,我們通過get_text( )方法就可以得到xxxx了。

好了,鋪墊做的差不多了,上程式碼咯~~~

案例:愛卡汽車

使用Python3,需要提前安裝bs4庫,博主的環境是win7+Python3+Pycharm(有時候也用Ubuntu16.04+Python3+Pycharm),很多時候都有人問博主,什麼ide好用呢?jupyter notebook?spyder?Pycharm?這裡只能和大家說各個ide各有千秋,做工程(如爬蟲)使用pycharm肯定是首選,如果只是平時的練習,寫個小程式,使用jupyter notebook和spyder就不錯,總之,如果涉及到頻繁列印輸出結果的東西,最好還是用pycharm,不要用jupyter notebook,不然會很卡。

言歸正傳,上程式碼!

兩點說明:爬蟲程式碼中,html程式碼經常會出現’class’這個屬性名,而class是python中“類”的關鍵字,而爬蟲的find方法對於屬性名而言,是不需要加引號的,如果直接輸入class是會出現問題的,所以需要注意,每次輸入class時應當輸入為class_,即class後加一個下劃線;

第二就是下方程式碼一開始有一個add_header的過程,為的是將程式碼偽裝成瀏覽器。很多網站是反對爬蟲程式對其資訊進行爬取的,所以會禁止一些程式訪問他們的網站,通過add_header將你的爬蟲程式偽裝成了瀏覽器,故在網站看來,訪問它的就不是一個程式,而是一個瀏覽器,或者說是一個人類使用者了。

import urllib
import urllib.request
from bs4 import BeautifulSoup
import re
import random
import time

# 設定目標url,使用urllib.request.Request建立請求
url0 = "http://newcar.xcar.com.cn/257/review/0.htm"
req0 = urllib.request.Request(url0)

# 使用add_header設定請求頭,將程式碼偽裝成瀏覽器
req0.add_header("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36")

# 使用urllib.request.urlopen開啟頁面,使用read方法儲存html程式碼
html0 = urllib.request.urlopen(req0).read()

# 使用BeautifulSoup建立html程式碼的BeautifulSoup例項,存為soup0
soup0 = BeautifulSoup(html0)

# 獲取尾頁(對照前一小節獲取尾頁的內容看你就明白了)
total_page = int(soup0.find("div",class_= "pagers").findAll("a")[-2].get_text())
myfile = open("aika_qc_gn_1_1_1.txt","a")
print("user","來源","認為有用人數","型別","評論時間","comment",sep="|",file=myfile)
for i in list(range(1,total_page+1)):
    # 設定隨機暫停時間
    stop = random.uniform(1, 3)
    url = "http://newcar.xcar.com.cn/257/review/0/0_" + str(i) + ".htm"
    req = urllib.request.Request(url)
    req.add_header("User-Agent","Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36")
    html = urllib.request.urlopen(req).read()
    soup = BeautifulSoup(html)
    contents = soup.find('div', class_="review_comments").findAll("dl")
    l = len(contents)
    for content in contents:
        tiaoshu = contents.index(content)
        try:
            ss = "正在爬取第%d頁的第%d的評論,網址為%s" % (i, tiaoshu + 1, url)
            print(ss)
            try:
                comment_jiaodu = content.find("dt").find("em").find("a").get_text().strip().replace("\n","").replace("\t","").replace("\r","")
            except:
                comment_jiaodu = ""
            try:
                comment_type0 = content.find("dt").get_text().strip().replace("\n","").replace("\t","").replace("\r","")
                comment_type1 = comment_type0.split("【")[1]
                comment_type = comment_type1.split("】")[0]
            except:
                comment_type = "好評"
            # 認為該條評價有用的人數
            try:
                useful = int(content.find("dd").find("div",class_ = "useful").find("i").find("span").get_text().strip().replace("\n","").replace("\t","").replace("\r",""))
            except:
                useful = ""
            # 評論來源
            try:
                comment_region = content.find("dd").find("p").find("a").get_text().strip().replace("\n","").replace("\t","").replace("\r","")
            except:
                comment_region = ""
            # 評論者名稱
            try:
                user = content.find("dd").find("p").get_text().strip().replace("\n","").replace("\t","").replace("\r","").split(":")[-1]
            except:
                user = ""
            # 評論內容
            try:
                comment_url = content.find('dt').findAll('a')[-1]['href']
                urlc = comment_url
                reqc = urllib.request.Request(urlc)
                reqc.add_header("User-Agent",
                                "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36")
                htmlc = urllib.request.urlopen(reqc).read()
                soupc = BeautifulSoup(htmlc)
                comment0 = \
                soupc.find('div', id='mainNew').find('div', class_='maintable').findAll('form')[1].find('table',class_='t_msg').findAll('tr')[1]
                try:
                    comment = comment0.find('font').get_text().strip().replace("\n", "").replace("\t", "")
                except:
                    comment = ""
                try:
                    comment_time = soupc.find('div', id='mainNew').find('div', class_='maintable').findAll('form')[1].find('table', class_='t_msg').\
                    find('div', style='padding-top: 4px;float:left').get_text().strip().replace("\n","").replace( "\t", "")[4:]
                except:
                    comment_time = ""
            except:
                try:
                    comment = content.find("dd").get_text().split("\n")[-1].split('\r')[-1].strip().replace("\n", "").replace("\t","").replace("\r", "").split(":")[-1]
                except:
                    comment = ""
            # time.sleep(stop)
            print(user,comment_region,useful,comment_type,comment_time,comment, sep="|", file=myfile)
        except:
            s = "爬取第%d頁的第%d的評論失敗,網址為%s" % (i, tiaoshu + 1, url)
            print(s)
            pass
myfile.close()


補充說明一下:try——except這個結構(看起來有點像if——else的結構)是一個非常重要的過程,為了使爬蟲程式碼可以良好的執行,不至於剛開始爬幾分鐘就報錯這種噁心人的情況,需要很好的利用try——except過程。程式會先執行try下的語句,如果發生失敗,就會執行except下的語句,你也可以使用多個try——except巢狀的結構完成複雜的情況的覆蓋,最好要保證你的try——except過程包含了程式會遇到的所有情況,那麼你的程式碼就是趨於完美的。

講到這裡,第一節爬蟲課程也就到這裡了,不久之後會介紹動態爬蟲,如果之後還有時間,還會介紹一下selenium這個模擬瀏覽的庫,以及爬蟲框架還有反爬蟲的知識,給自己打個廣告,除了爬蟲可,近期也會分享一些關於word2vec和fastText文字分類演算法的內容,讀者有什麼其他想交流的可以留言~我也是個正在學習路上的仔,希望能和各路朋友以及大牛交流。

相關推薦

Python新手漂亮爬蟲程式碼

BeautifulSoup神器Python一個第三方庫bs4中有一個BeautifulSoup庫,是用於解析html程式碼的,換句話說就是可以幫助你更方便的通過標籤定位你需要的資訊。這裡只介紹兩個比較關鍵的方法:1、find方法和findAll方法: 首先,Beautiful

驚!女朋友用Python幾行程式碼就監控了我的電腦,吃雞被發現了

    今天帶給大家一個非常有意思的 python 程式,基於 itchat 實現微信控制電腦。你可以通過在微信傳送命令,來拍攝當前電腦的使用者,然後圖片會發送到你的微信上。甚至你可以傳送命令來遠端關閉電腦。 學習Python中有不明白推薦加入交流裙  

怎樣漂亮整潔的程式碼?聊聊 Clean Code 的編碼、重構技巧

Clean Code,顧名思義就是整潔的程式碼,或者說清晰、漂亮的程式碼,相信大多數工程師都希望自己能寫出這樣的程式碼。 也許這是個千人千面的話題,每個工程師都有自己的理解。比如我,從一個天天被罵程式碼寫得爛的人,逐漸學習成長,到現在也能寫的出“人模人樣”的程式碼來

漂亮程式碼的7種方法

很多開發者不願意使用空白,就好像這要收費一樣。我在此並非刻意地新增空白,粗魯地打斷程式碼的連貫性。在實際編寫程式碼的過程中,會很容易地發現在什麼地方加入空白,這不但美觀而且讓讀者易懂,如下:1 function getSomeAngle() {2    // Some code here then3    r

程式設計師如何優雅的程式碼

一直以來,關於“程式碼規範”的話題都備受關注,業界甚至有很多流傳甚廣的段子不斷調侃之。既然程式碼規範能引起這麼大的共鳴,那麼今天我們談談一個程式設計師的自我修養——如何寫出優雅的程式碼? Martin(Bob大叔)曾在《程式碼整潔之道》一書中說:當你的程式碼在做 Code Review 時,審查

5分鐘學會Markdown語法,在GitHub上漂亮文字,提升別人閱讀體驗

今天研究下在GitHub中如何漂亮的書寫readme部分 markdown是一種純文字格式的標記語言。通過簡單的標記語法,它可以使普通文字內容具有一定的格式。 1、因為是純文字,所以只要支援markdown的地方都能獲得一樣的編輯效果,可以讓作者擺脫排版的困擾,專心寫作。 2、操作簡單。

《程式設計珠璣》程式碼之路12:如何用C/C++實現array[-1]並利用它優美的程式碼

我們就以最大子陣列和為例: 最大子段和問題:給一組數,計算最大子段和。 在部落格:最大欄位和的6種解法,解法三中,我們提到了儲存前i項和的操作: cache[i]代表前i-1項之和,因為在c/c++中,cache[-1]會越界,所以如果用cache[i]代表前i項和的話,那麼在用遞推公式

力薦!這些工具可以幫你乾淨的程式碼

作者|Adeel Imran譯者|無明 想寫出好程式碼,卻不知道從哪裡開始?想刪除死程式碼?想在程式碼庫中找出未被使用的變數?想在程式碼中找出有問題的模式? 你是多元化團隊的負責人嗎?你的團隊中有新來的開發人員嗎?你擔心他們會寫出不符合標準的程式碼嗎?在程式碼評審時是否花了一整天的時間去檢查程式碼標準,而

優質Java程式碼的4個技巧

我們平時的程式設計任務不外乎就是將相同的技術套件應用到不同的專案中去,對於大多數情況來說,這些技術都是可以滿足目標的。然而,有的專案可能需要用到一些特別的技術,因此工程師們得深入研究,去尋找那些最簡單但最有效的方法。本文我們將介紹一些有助於解決常見問題的通用設計策略和目標實現技術,即: 只做有目的性的優化

程式設計師如何才能優秀的程式碼

1、寫每個程式都是為了解決某個問題,你應該去思考我該怎樣去解決這問題,而不是急於 的去考慮我程式到底怎麼寫、怎麼去實現,往往有些同學他動手最快,寫得很積極,但他不 一定是寫的最好的,也不一定是最快寫出程式的人。所以當你遇到問題的時候,你需要不斷 的去思考,去想我怎樣去解決這問

程式碼積累】一手漂亮程式碼(1)

      自己寫程式碼的過程中,難免會發現一些問題,有的是共性的、有的是特例的,定期把自己總結的程式碼規律做個總結,寫成部落格,請見如下:      (1)屬性訪問器裡的get判斷 <span style="font-family:Microsoft YaHei;f

Python新手程式沒有思路怎麼辦

對於Python新手,在剛開始學習Python的時候,總會遇到這樣的一個問題:學習了相關教程,也明白相關的規則,但是給出一個功能,卻無從下手,不知道怎麼去實現,或者知道怎麼去實現,就是寫不出來,這個問題該如何解決呢? 出現以上的問題,主要是因為Python新手在學習時眼高手低,僅僅侷限於對於程式

Python丨給你的爬蟲程式碼裡面新增一些小功能,讓你的程式碼與眾不同

1. 爬蟲程式隨機暫停x秒 需要用到time和random兩個python自建庫。 用法:time.sleep(x) 程式暫停x秒    random.uniform(a, b):產生從a到b中的隨機浮點數    random.random():產生從0到1中的隨機浮點數,是unif

C/C++之高質量程式碼

      自從看了林銳博士的《高質量C++程式設計指南》以後,感覺自己以前寫的程式碼都是一些垃圾,真的low,根本不知道一些基本的程式設計規範,然後看了一些大神寫的程式碼,清晰易懂,而且還很漂亮,給人一種賞心悅目的感覺,寫一手高質量的程式碼,是一個程式設計師最基本的素養,

利用VBA在Word中排漂亮程式碼

引言 在學習程式設計的過程中,常常會使用word來做筆記,下面我將對如何利用word巨集來進行程式碼的排版進行說明 1.工具   我用的是word2007,word2003和word2010操作也差不多 2.基本操作   從visual s

java程式設計-如何優雅的程式碼

1. java判斷null!=a和a!=null的區別? 正常來說沒有區別,我們想判斷a是否為null, 可以寫if(a==null), 但是這有個問題,一不小心手滑了就寫成if(a=null). 在不少語言裡這是可以編譯&執行的,並且得不到你希望的結

java也能漂亮的介面(Java開源Swing外觀)

  Substance look & feel  這個專案的目的是提供一個流行的外觀(look & feel)。這個外觀(look & feel)聯合了Windows XP和MacOS 10.4最好的特性並且需要JDK 5.0以上。  JGoo

如何好的程式碼

設計 1、優雅需要付出代價。從短期利益來看,對某個問題提出優雅的解決方法,似乎可能花你更多的時間。但當它終於能夠正確執行並可輕易套用於新案例中,不需要花上數以時計,甚至以天計或以月計的辛苦代價時,你會看得到先前所花功夫的回報(即使沒有人可以衡量這一點)。這不僅給你一個可

只用這 6 個字元,就可以任意 JavaScript 程式碼

你可能在網上見過有人用 幾個不同的字元寫的各種稀奇古怪的 JavaScript 程式碼,雖然看起來奇怪,但是能正常執行!比如這個: (!(~+[])+{})[--[~+""][+[]]*[~+[]] + ~~!+[]]+({}+[])[[~!+[]]*~+[]] 你猜執行結果是什麼?你可以