1. 程式人生 > >初級爬蟲第二天

初級爬蟲第二天

在哪裏 初級 匿名 另一個 import 分享 不知道 linu pst

介紹了2種反爬的方式:

  • 請求頭
  • 代理IP

一、反爬手段1——向請求頭中添加User-Agent:

請求頭、響應頭:

1.響應頭:response_header

響應頭response_header,可以通過response對象.headers,獲取得到。

response.headers,得到的是響應頭信息

 1 def load():
 2     # 1.目標網頁URL地址
 3     URL = "http://www.baidu.com/"
 4 
 5     # 2.發送網絡請求:
 6     # 返回response對象,使用response對象接收服務器返回的數據
7 response = urllib.request.urlopen(URL) 8 9 # 得到響應頭信息 10 print(response.headers) 11 12 load()

結果為:

 1 Bdpagetype: 1
 2 Bdqid: 0xbfd0e4790001890b
 3 Cache-Control: private
 4 Content-Type: text/html
 5 Cxy_all: baidu+739fcb9dd92b830634cd2f957c8e6f67
 6 Date: Fri, 03 May 2019 15:30:05 GMT
7 Expires: Fri, 03 May 2019 15:29:21 GMT 8 P3p: CP=" OTI DSP COR IVA OUR IND COM " 9 Server: BWS/1.1 10 Set-Cookie: BAIDUID=2D1BE12D094679CAE43187C509B76E5D:FG=1; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com 11 Set-Cookie: BIDUPSID=2D1BE12D094679CAE43187C509B76E5D; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com
12 Set-Cookie: PSTM=1556897405; expires=Thu, 31-Dec-37 23:55:55 GMT; max-age=2147483647; path=/; domain=.baidu.com 13 Set-Cookie: delPer=0; path=/; domain=.baidu.com 14 Set-Cookie: BDSVRTM=0; path=/ 15 Set-Cookie: BD_HOME=0; path=/ 16 Set-Cookie: H_PS_PSSID=28884_1454_21091_28724_28963_28837_28584; path=/; domain=.baidu.com 17 Vary: Accept-Encoding 18 X-Ua-Compatible: IE=Edge,chrome=1 19 Connection: close 20 Transfer-Encoding: chunked

和瀏覽器中f12,network中的Response Headers顯示的信息對比,基本一致

技術分享圖片

2.請求頭:request_header(重點)

User-Agent是在模擬真實用戶發送網絡請求

(1)目的:我們要向請求頭裏面,添加User-Agent信息,這樣就可以幹掉一部分的反爬手段。

(2)request = urllib.request.Request(目標網頁URL地址)

——創建request對象

要想獲取請求頭request_header,我們需要先創建request對象,然後通過request對象獲取請求頭。

註意:Request()首字母必須大寫

(3)request.headers,就可以得到請求頭的信息。

(4)request.add_header(‘User_Agent‘, ‘xxx‘)

——向請求頭中添加‘User-Agent’信息

使用爬蟲,最開始時,請求頭request_header中是空的,為了模擬真實用戶,需要向請求頭request_header中添加信息;必須先創建request對象之後,再向request_header中添加請求頭信息。

技術分享圖片

xxx就是冒號(:)後面的那些

(5)response = urllib.request.urlopen(request)

發送網絡請求,這個方法的參數,既可以是URL地址,也可以是request對象。

(6)request.get_header(‘User-agent‘)

——獲取請求頭信息的第二種方式

註意:

a. 這裏的參數是‘User-agent‘,只有U大寫,A小寫;

request.add_header()中,"User-Agent",U和A都大寫。

b. request.get_header(),這個方法只能得到請求頭的一部分信息

如:request.get_header(‘User-agent‘)只會得到User-Agent信息

技術分享圖片

而request.headers,得到的是請求頭的全部信息

(7)request.get_full_url()

可以得到完整的URL

(8)添加User-Agent信息,爬取百度首頁

 1 import urllib.request
 2 import urllib.parse
 3 
 4 #爬取百度首頁https://www.baidu.com/
 5 def load():
 6     #1.目標網頁URL
 7     URL = "https://www.baidu.com/"
 8     
 9     #2.向請求頭中添加User-Agent信息
10     #2.1創建request對象,參數為目標網頁的URL
11     request = urllib.request.Request(URL)
12     
13     #打印最開始時請求頭的User-Agent
14     print(request.get_header(User-agent))
15     #2.2向請求頭中添加User-Agent信息
16     request.add_headers(User-Agent, Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36)
17     
18     #再次打印請求頭的User-Agent
19     print(request.get_header(User-agent))
20     
21     #3.發送網絡請求,response接收返回數據
22     #參數填寫添加User-Agent信息之後的request對象
23     response = urllib.request.urlopen(request)
24     
25 load()

結果:

技術分享圖片

可以看到,一開始時,User-Agent的信息為None,添加之後,為我們添加的信息

註意:發送網絡請求的代碼,urllib.request.urlopen(request)參數填寫request對象,而非URL;

如果填URL,則發送請求的請求頭沒有添加我們添加的User-Agent信息,還是為空None。

1.5 使用多個User-Agent:

(1)由於爬蟲會在極短的時間內(一秒鐘),訪問服務器很多次(幾百次)。所以,如果只使用一個User-Agent,很容易被服務器識別為爬蟲。

(2)反爬手段2.5:使用多個User-Agent

  • 百度搜索:User-Agent大全
  • 使用fake User-Agent(包含250個User-Agent)
  • User-Agent池(推薦)

——這樣,每次發送網絡請求的瀏覽器信息和個人信息都不一樣,就可以幹掉反爬了

(3)思路:設置一個User-Agent的列表,每次從中隨機選取一個User-Agent

(4)代碼:

import urllib.request
import urllib.parse
import random
 
#爬取百度首頁https://www.baidu.com/
def load():
    #1.目標網頁URL
    URL = "https://www.baidu.com/"
     
    #2.向請求頭中添加User-Agent信息
    #2.1 設置User-Agent池:
    user_agent_list = [Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60,
                   Opera/8.0 (Windows NT 5.1; U; en),
                   Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50,
                   Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50,
                   Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0,
                   Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10;,
                   Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60,
                   Opera/8.0 (Windows NT 5.1; U; en),
                   Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50,
                   Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50,
                   Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0,
                   Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10,
                   Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2,
                   Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36,
                   ]
                  
    #2.2 從User-Agent池中隨機選擇一個User-Agent
    choose_user_agent = random.choice(user_agent_list)
    
    #2.2創建request對象,參數為目標網頁的URL
    request = urllib.request.Request(URL)
    
    #打印最開始時請求頭的User-Agent
    print(request.get_header(User-agent))
    #2.2向請求頭中添加User-Agent信息
    request.add_headers(User-Agent, choose_user_agent)

    
    #再次打印請求頭的User-Agent
    print(request.get_header(User-agent))
    
    #3.發送網絡請求,response接收返回數據
    #參數填寫添加User-Agent信息之後的request對象
    response = urllib.request.urlopen(request)
    
load()

二、反爬手段2——代理IP:

理論:

(1)IP分為免費IP和付費IP:

1.1 免費IP:時效性差,錯誤率高

1.2 付費IP:時效性強,錯誤率低,但是也有失效的IP

(2)IP的三種叫法:

2.1 透明IP:對方知道我自己的真實IP

2.2 匿名IP:對方不知道我自己的真實IP,但是知道我使用了代理IP

2.3 高匿名IP:對方不知道我自己的真實IP,也不知道我使用了代理IP

技術分享圖片

技術分享圖片

註:由圖可以發現,代理IP分為HTTP和HTTPS,可以根據自己的需求,找自己要的類型IP

(3)IP分為免費IP寫法和付費IP寫法

(4)發送網絡請求,需要使用我們自己添加的代理IP。看上面的爬蟲代碼,可以發現:在發送網絡請求之前,只涉及到兩個東西,一個是request對象、另一個是urllib.request.urlopen()方法。

查看request和urlopen()

技術分享圖片

技術分享圖片

通過查看request對象和urlopen()方法源碼,發現這兩個對象,都沒有提供加入代理IP的位置。

所以,我們應該在哪裏加入,我們自己想要偽裝的代理IP呢???

查看urlopen()方法代碼

技術分享圖片

發現:該方法的本質是創建了一個opener對象,返回的是opener.open()

而opener對象,又是通過build_opener()一個handler處理器對象得來的

技術分享圖片

所以說,如果能在handler對象中加入我們要偽裝的代理IP,然後用該對象創建opener對象,再調用open()方法,就可以達到我們的目的:偽裝使用代理IP向服務器發送網絡請求。

總結一下:

  1. urlopen()和request對象都沒有添加IP的方法
  2. urlopen()的底層本質上是:先創建handler對象,然後創建opener對象,再用opener.open()的方法發送網絡請求,爬取數據。
  3. 我們需要創建一個能夠添加代理IP的handler處理器——proxyhandler,然後利用它創建opener對象,最後發送請求。

代碼:

import urllib.request
import urllib.parse
import string
import random


# 使用添加的User-Agent和代理IP,爬取搜狗搜索的首頁
def load():
    # 1.目標網頁URL:
    URL = https://www.sogou.com/

    # 2.向請求頭添加User-Agent
    # 2.1創建request對象
    request = urllib.request.Request(URL)
    # 2.2設置User-Agent池
    User_Agent_List = [
        Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60,
        Opera/8.0 (Windows NT 5.1; U; en),
        Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50,
        Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50,
        Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0,
        Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10;,
        Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36 OPR/26.0.1656.60,
        Opera/8.0 (Windows NT 5.1; U; en),
        Mozilla/5.0 (Windows NT 5.1; U; en; rv:1.8.1) Gecko/20061208 Firefox/2.0.0 Opera 9.50,
        Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; en) Opera 9.50,
        Mozilla/5.0 (Windows NT 6.1; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0,
        Mozilla/5.0 (X11; U; Linux x86_64; zh-CN; rv:1.9.2.10) Gecko/20100922 Ubuntu/10.10 (maverick) Firefox/3.6.10,
        Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2,
        Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36,
        ]
    # 2.3每次請求隨機選擇一個User-Agent
    choose_User_Agent = random.choice(User_Agent_List)
    # 2.4向請求頭信息中,添加User-Agent
    request.add_header(User-Agent, choose_User_Agent)

    # 3.添加代理IP
    # 3.1設置代理IP
    proxy_ip = {https: 116.52.13.90:808}
    # 3.2創建handler處理器對象
    proxy_handler = urllib.request.ProxyHandler(proxy_ip)
    # 3.3創建opener對象(因為真正發送網絡請求的是opener而非handler)
    opener = urllib.request.build_opener(proxy_handler)
    # 3.4調用open方法,發送網絡請求
    response = opener.open(request)

    # 4.發送網絡請求,使用response對象接收數據
   #因為3.4中已經做了
    # 5.讀取response對象裏面的數據,轉碼為字符串格式
    str_data = response.read().decode(utf-8)
    # 6.保存數據
    with open(sougou.com02.html, w, encoding=utf-8) as f:
        f.write(str_data)


load()

註意:

(1)代理IP的設置格式:

1.1 使用字典放置

1.2 鍵key:相應的代理IP的類型(http或者https)

1.3 值value:代理IP:端口號

1.4 鍵http/https;值IP地址+端口號,均使用字符串格式

eg:

proxy = {‘http‘: "115.223.69.54:8010", "https": "116.209.52.248:9999"}

(2)opener.open()中的參數,既可以是目標網頁的URL也可以是request對象。這裏由於,我們要使用添加的User-Agent,所以參數用request對象。

初級爬蟲第二天