和我一塊兒學爬蟲(一)

 

前幾天就想寫一個爬蟲系列的文章,由於比較忙因此沒有寫(還不是由於懶),趁着如今屋裏比較的涼爽,心也比較的靜,總結下目前遇到的一些爬蟲知識,本系列將從簡單的爬蟲開始提及,之後會逐漸的提高難度,同時會對反爬手段作一個總結,以及用具體的事例來演示,不一樣的反爬現象和實現手段。php

前言

本系列側重點是應用和實戰,因此,對於軟件的安裝這些基本操做不作詳細講解,我這裏認爲你已經有了必定的python基礎,因此對於python的安裝必定會有必定的瞭解了,這裏廢話很少說讓咱們進入正題。html

環境準備

鑑於大多數人的系統是windows系統,因此這裏的全部內容都是在Windows下進行的,另外推薦安裝瀏覽器,使用語言python,版本3.6(低版本不能使用requests_html)。主要的爬蟲模塊requests_html。node

爬蟲具有的基本條件

做爲一個合格的爬蟲,首先得有一個headers,如何理解headers,咱們打開瀏覽器,而後F12,選擇network選項卡,打開百度的首頁,而後打開而後選擇其中的一個連接,而後點擊新彈出的窗口的headers,看到有一個'Request Headers',咱們看到下面紅框的內容,這些由:組成的數據結構,共同構成了一個headers,在python中能夠把這些字段做爲一個字典傳入。python

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

爬蟲的代碼實現

下面我來看一個基本爬蟲代碼,爬取百度的導航欄文字內容。
1.導入requests_html模塊。windows

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屬性的。session

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 | 地圖 | 視頻 | 貼吧 | 學術 | 登陸 | 設置 | 更多產品

watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=

相關文章
相關標籤/搜索