天天看點

和我一起入門python爬蟲

前幾天就想寫一個爬蟲系列的文章,因為比較忙是以沒有寫(還不是因為懶),趁着現在屋裡比較的涼爽,心也比較的靜,總結下目前遇到的一些爬蟲知識,本系列将從簡單的爬蟲開始說起,後會逐漸的提升難度,同時會對反爬手段做一個總結,以及用具體的事例來示範,不同的反爬現象和實作手段。

前言

本系列側重點是應用和實戰,是以,對于軟體的安裝這些基本操作不做詳細講解,我這裡認為你已經有了一定的python基礎,是以對于python的安裝一定會有一定的了解了,這裡廢話不多說讓我們進入正題。

環境準備

鑒于大多數人的系統是windows系統,是以這裡的所有内容都是在Windows下進行的,另外推薦安裝谷歌浏覽器,使用語言python,版本3.6(低版本不能使用requests_html)。主要的爬蟲子產品requests_html。

爬蟲具備的基本條件

作為一個合格的爬蟲,首先得有一個headers,如何了解headers,我們打開谷歌浏覽器,然後F12,選擇network頁籤,打開百度的首頁,然後打開然後選擇其中的一個連結,然後點選新彈出的視窗的headers,看到有一個'Request Headers',我們看到下面紅框的内容,這些由:組成的資料結構,共同構成了一個headers,在python中可以把這些字段作為一個字典傳入。

和我一起入門python爬蟲

爬蟲的代碼實作

下面我來看一個基本爬蟲代碼,爬取百度的導航欄文字内容。

1.導入requests_html子產品。

from requests_html import HTMLSession
           

2.建立一給session對象,目的是維持一次完整的會話。

session=HTMLSession()
           

3.通過get方法通路網絡

url='https://www.baidu.com'
headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36'}
req=session.get(url=url,headers=headers)
           

get方法需要傳入兩個參數,一個是url,一個是headers(字典類型)。一般的我們傳入一個user_agent就可以愉快的使用了。(這裡隻是說一般的對于有先網站伺服器還會監測headers的其他屬性内容)。我們會擷取一個response對象。

拓展:如果檢視requests_html的源碼會發現預設是給了幾個headers屬性的。

def default_headers():

    """

    :rtype: requests.structures.CaseInsensitiveDict

    """

    return CaseInsensitiveDict({

        'User-Agent': default_user_agent(),  #這個就是一個随機的useragent

        'Accept-Encoding': ', '.join(('gzip', 'deflate')),#接收編碼類型

        'Accept': '*/*',#接收檔案類型

        'Connection': 'keep-alive',#保持連結

    })
           

4.擷取網頁傳回的狀态碼

一般的我們把200狀态碼認為是響應成功(并不一定是你想要的結果,比如登陸失敗有些也是200)。

其他常見的還有,404網頁通路失敗,500伺服器拒絕通路,302和301作為網頁的重定向。

if req.status_code==200:

   print("ok")
           

5.擷取正确的網頁編碼

因為每個頁面的編碼不同,可能導緻在解析的時候出現亂碼的情況,對此requests_html子產品為我們提供了一個可以高準确率擷取編碼的方法,目前來看對于絕大對數html頁面是沒有問題的,是以可以放心使用。

req.encoding=req.apparent_encoding
           

6.檢視擷取html源碼

此時我們已經擷取了編碼之後的對象了,如果我們需要檢視擷取的内容以及編碼是否正确我們可以使用text屬性來擷取網頁的源碼,它是一個字元串格式的。

7.xpath表達式的使用

requets_html子產品的一個好處就是集合了衆多的網頁解析子產品比如,bs4,pyquery,lxml等,可以說相當的強大了,requests_html通過response的html屬性調用xpath方法,來直接操作dom對象,通過觀察我們擷取百度導航欄的标題的xpath,代碼我們可以這樣寫。

 node_list=req.html.xpath("//div[@id='u1']/a/text()")
           

簡單說下上面xpath表達式的含義,//從比對選擇的目前節點選擇文檔中的節點,而不考慮它們的位置。/表示從根節點選取。後面跟的ediv表示是div節點,中括号裡面一般是做屬性判斷@id就是判斷id屬性然後取其值為ul的,後面緊跟的/a,表示上面div節點的下級所有含有a的節點,然後後面的text()是表示擷取該節點的文本資訊。

8.綜合整理下上面的代碼如下:

from requests_html import HTMLSession

from traceback import format_exc
class BaiDu():

   def __init__(self):

       self.session=HTMLSession()

       self.url='https://www.baidu.com'

       self.headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.62 Safari/537.36'}

       self.timeout=20

   def gethtml(self):

       try:

           req=self.session.get(url=self.url,headers=self.headers,timeout=self.timeout)

           if req.status_code==200:

               req.encoding=req.apparent_encoding

               title_info=self.parse_html(req)

               return ' | '.join(title_info)

       except:

           print("出錯了錯誤内容是",format_exc)



   def parse_html(self,req):

       node_list=req.html.xpath("//div[@id='u1']/a/text()")

       return node_list
if __name__ == '__main__':

        baidu=BaiDu()

        title=baidu.gethtml()

        print(title)
           

輸出結果:

新聞 | hao123 | 地圖 | 視訊 | 貼吧 | 學術 | 登入 | 設定 | 更多産品
           

好了,今天的内容就到這,内容比較的簡單,簡單的說了下爬蟲的基本思路,後面會一步步加大難度,如有任何問題和疑問歡迎留言,如果您喜歡我的文章不防動動小手,轉發到朋友圈分享給更多的朋友。

繼續閱讀