在前面我們介紹了多種請求庫,如 Requests、Urllib、Selenium 等。我們接下來首先貼近實戰,了解一下代理怎么使用,為后面了解代理池、ADSL 撥號代理的使用打下基礎。
下面我們來梳理一下這些庫的代理的設置方法。
1. 獲取代理
在做測試之前,我們需要先獲取一個可用代理,搜索引擎搜索“代理”關鍵字,就可以看到有許多代理服務網站,在網站上會有很多免費代理,比如西刺:http://www.xicidaili.com/,這里列出了很多免費代理,但是這些免費代理大多數情況下都是不好用的,所以比較靠譜的方法是購買付費代理,很多網站都有售賣,數量不用多,買一個穩定可用的即可,可以自行選購。
或者如果我們本機有相關代理軟件的話,軟件一般會在本機創建 HTTP 或 SOCKS 代理服務,直接使用此代理也可以。
在這里我的本機安裝了一部代理軟件,它會在本地 9743 端口上創建 HTTP 代理服務,也就是代理為 127.0.0.1:9743,另外還會在 9742 端口創建 SOCKS 代理服務,也就是代理為 127.0.0.1:9742,我只要設置了這個代理就可以成功將本機 IP 切換到代理軟件連接的服務器的 IP了。
所以本節下面的示例里我使用上述代理來演示其設置方法,你可以自行替換成自己的可用代理,設置代理后測試的網址是:http://httpbin.org/get,訪問該站點可以得到請求的一些相關信息,其中 origin 字段就是客戶端的 IP,我們可以根據它來判斷代理是否設置成功,也就是是否成功偽裝了IP。
下面我們來看下各個庫的代理設置方式。
2. Urllib
首先我們以最基礎的 Urllib 為例,來看一下代理的設置方法,代碼如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
from urllib.error import URLError from urllib.request import ProxyHandler, build_opener proxy = '127.0.0.1:9743' proxy_handler = ProxyHandler({ 'http' : 'http://' + proxy, 'https' : 'https://' + proxy }) opener = build_opener(proxy_handler) try : response = opener. open ( 'http://httpbin.org/get' ) print (response.read().decode( 'utf-8' )) except URLError as e: print (e.reason) |
運行結果如下:
1
2
3
4
5
6
7
8
9
10
11
|
{ "args" : {}, "headers" : { "Accept-Encoding" : "identity" , "Connection" : "close" , "Host" : "httpbin.org" , "User-Agent" : "Python-urllib/3.6" }, "origin" : "106.185.45.153" , "url" : "http://httpbin.org/get" } |
在這里我們需要借助于 ProxyHandler 設置代理,參數是字典類型,鍵名為協議類型,鍵值是代理,注意此處代理前面需要加上協議,即 http 或者 https,此處設置了 http 和 https 兩種代理,當我們請求的鏈接是 http 協議的時候,它會調用 http 代理,當請求的鏈接是 https 協議的時候,它會調用https代理,所以此處生效的代理是:http://127.0.0.1:9743。
創建完 ProxyHandler 對象之后,我們需要利用 build_opener() 方法傳入該對象來創建一個 Opener,這樣就相當于此 Opener 已經設置好代理了,接下來直接調用它的 open() 方法即可使用此代理訪問我們所想要的鏈接。
運行輸出結果是一個 Json,它有一個字段 origin,標明了客戶端的 IP,此處的 IP 驗證一下,確實為代理的 IP,而并不是我們真實的 IP,所以這樣我們就成功設置好代理,并可以隱藏真實 IP 了。
如果遇到需要認證的代理,我們可以用如下的方法設置:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
from urllib.error import URLError from urllib.request import ProxyHandler, build_opener proxy_handler = ProxyHandler({ 'http' : 'http://' + proxy, 'https' : 'https://' + proxy }) opener = build_opener(proxy_handler) try : response = opener. open ( 'http://httpbin.org/get' ) print (response.read().decode( 'utf-8' )) except URLError as e: print (e.reason) |
這里改變的只是 proxy 變量,只需要在代理前面加入代理認證的用戶名密碼即可,其中 username 就是用戶名,password 為密碼,例如 username 為foo,密碼為 bar,那么代理就是 foo:[email protected]:9743。
如果代理是 SOCKS5 類型,那么可以用如下方式設置代理:
1
2
3
4
5
6
7
8
9
10
11
12
|
import socks import socket from urllib import request from urllib.error import URLError socks.set_default_proxy(socks.SOCKS5, '127.0.0.1' , 9742 ) socket.socket = socks.socksocket try : response = request.urlopen( 'http://httpbin.org/get' ) print (response.read().decode( 'utf-8' )) except URLError as e: print (e.reason) |
此處需要一個 Socks 模塊,可以通過如下命令安裝:
1
|
pip3 install PySocks |
本地我有一個 SOCKS5 代理,運行在 9742 端口,運行成功之后和上文 HTTP 代理輸出結果是一樣的:
1
2
3
4
5
6
7
8
9
10
11
|
{ "args" : {}, "headers" : { "Accept-Encoding" : "identity" , "Connection" : "close" , "Host" : "httpbin.org" , "User-Agent" : "Python-urllib/3.6" }, "origin" : "106.185.45.153" , "url" : "http://httpbin.org/get" } |
結果的 origin 字段同樣為代理的 IP,設置代理成功。
3. Requests
對于 Requests 來說,代理設置更加簡單,我們只需要傳入 proxies 參數即可。
還是以上例中的代理為例,我們來看下 Requests 的代理的設置:
1
2
3
4
5
6
7
8
9
10
11
12
|
import requests proxy = '127.0.0.1:9743' proxies = { 'http' : 'http://' + proxy, 'https' : 'https://' + proxy, } try : response = requests.get( 'http://httpbin.org/get' , proxies = proxies) print (response.text) except requests.exceptions.ConnectionError as e: print ( 'Error' , e.args) |
運行結果:
1
2
3
4
5
6
7
8
9
10
11
12
|
{ "args" : {}, "headers" : { "Accept" : "*/*" , "Accept-Encoding" : "gzip, deflate" , "Connection" : "close" , "Host" : "httpbin.org" , "User-Agent" : "python-requests/2.18.1" }, "origin" : "106.185.45.153" , "url" : "http://httpbin.org/get" } |
可以發現 Requests 的代理設置比 Urllib 簡單很多,只需要構造代理字典即可,然后通過 proxies 參數即可設置代理,不需要重新構建 Opener。
可以發現其運行結果的 origin 也是代理的 IP,證明代理已經設置成功。
如果代理需要認證,同樣在代理的前面加上用戶名密碼即可,代理的寫法就變成:
1
|
|
和 Urllib 一樣,只需要將 username 和 password 替換即可。
如果需要使用 SOCKS5 代理,則可以使用如下方式:
1
2
3
4
5
6
7
8
9
10
11
12
|
import requests proxy = '127.0.0.1:9742' proxies = { 'http' : 'socks5://' + proxy, 'https' : 'socks5://' + proxy } try : response = requests.get( 'http://httpbin.org/get' , proxies = proxies) print (response.text) except requests.exceptions.ConnectionError as e: print ( 'Error' , e.args) |
在這里需要額外安裝一個 Socks 模塊,命令如下:
1
|
pip3 install "requests[socks]" |
運行結果是完全相同的:
1
2
3
4
5
6
7
8
9
10
11
12
|
{ "args" : {}, "headers" : { "Accept" : "*/*" , "Accept-Encoding" : "gzip, deflate" , "Connection" : "close" , "Host" : "httpbin.org" , "User-Agent" : "python-requests/2.18.1" }, "origin" : "106.185.45.153" , "url" : "http://httpbin.org/get" } |
另外還有一種設置方式,和 Urllib 中的方法相同,使用 socks 模塊,也需要像上文一樣安裝該庫,設置方法如下:
1
2
3
4
5
6
7
8
9
10
11
|
import requests import socks import socket socks.set_default_proxy(socks.SOCKS5, '127.0.0.1' , 9742 ) socket.socket = socks.socksocket try : response = requests.get( 'http://httpbin.org/get' ) print (response.text) except requests.exceptions.ConnectionError as e: print ( 'Error' , e.args) |
這樣也可以設置 SOCKS5 代理,運行結果完全相同,相比第一種方法,此方法是全局設置,不同情況可以選用不同的方法。
4. Selenium
Selenium 同樣也可以設置代理,在這里分兩種介紹,一個是有界面瀏覽器,以 Chrome 為例介紹,另一種是無界面瀏覽器,以 PhantomJS 為例介紹。
Chrome
對于 Chrome 來說,用 Selenium 設置代理的方法也非常簡單,設置方法如下:
1
2
3
4
5
6
7
|
from selenium import webdriver proxy = '127.0.0.1:9743' chrome_options = webdriver.ChromeOptions() chrome_options.add_argument( '--proxy-server=http://' + proxy) browser = webdriver.Chrome(chrome_options = chrome_options) browser.get( 'http://httpbin.org/get' ) |
在這里我們通過 ChromeOptions 來設置代理,在創建 Chrome 對象的時候通過 chrome_options 參數傳遞即可。
這樣在運行之后便會彈出一個 Chrome 瀏覽器,訪問目標鏈接之后輸出結果如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
{ "args" : {}, "headers" : { "Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8" , "Accept-Encoding" : "gzip, deflate" , "Accept-Language" : "zh-CN,zh;q=0.8" , "Connection" : "close" , "Host" : "httpbin.org" , "Upgrade-Insecure-Requests" : "1" , "User-Agent" : "Mozilla / 5.0 (Macintosh; Intel Mac OS X 10_12_3 ) AppleWebKit / 537.36 (KHTML,like Gecko) Chrome / 59.0 . 3071.115 Safari / 537.36 " }, "origin" : "106.185.45.153" , "url" : "http://httpbin.org/get" } |
可以看到 origin 同樣為代理 IP 的地址,代理設置成功。
如果代理是認證代理,則設置方法相對比較麻煩,方法如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
from selenium import webdriver from selenium.webdriver.chrome.options import Options import zipfile ip = '127.0.0.1' port = 9743 username = 'foo' password = 'bar' manifest_json = """ { "version": "1.0.0", "manifest_version": 2, "name": "Chrome Proxy", "permissions": [ "proxy", "tabs", "unlimitedStorage", "storage", "<all_urls>", "webRequest", "webRequestBlocking" ], "background": { "scripts": ["background.js"] } } """ background_js = """ var config = { mode: "fixed_servers", rules: { singleProxy: { scheme: "http", host: "%(ip)s", port: %(port)s } } } chrome.proxy.settings.set({value: config, scope: "regular"}, function() {}); function callbackFn(details) { return { authCredentials: { username: "%(username)s", password: "%(password)s" } } } chrome.webRequest.onAuthRequired.addListener( callbackFn, {urls: ["<all_urls>"]}, ['blocking'] ) """ % { 'ip' : ip, 'port' : port, 'username' : username, 'password' : password} plugin_file = 'proxy_auth_plugin.zip' with zipfile.ZipFile(plugin_file, 'w' ) as zp: zp.writestr( "manifest.json" , manifest_json) zp.writestr( "background.js" , background_js) chrome_options = Options() chrome_options.add_argument( "--start-maximized" ) chrome_options.add_extension(plugin_file) browser = webdriver.Chrome(chrome_options = chrome_options) browser.get( 'http://httpbin.org/get' ) |
在這里需要在本地創建一個 manifest.json 配置文件和 background.js 腳本來設置認證代理,運行之后本地會生成一個 proxy_auth_plugin.zip 文件保存配置。
運行結果和上例一致,origin 同樣為代理 IP。
PhantomJS
對于 PhantomJS,代理設置方法可以借助于 service_args 參數,也就是命令行參數,代理設置方法如下:
1
2
3
4
5
6
7
8
|
from selenium import webdriver service_args = [ '--proxy=127.0.0.1:9743' , '--proxy-type=http' ] browser = webdriver.PhantomJS(service_args = service_args) browser.get( 'http://httpbin.org/get' ) print (browser.page_source) |
在這里我們只需要使用 service_args 參數,將命令行的一些參數定義為列表,在初始化的時候傳遞即可。
運行結果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
{ "args" : {}, "headers" : { "Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" , "Accept-Encoding" : "gzip, deflate" , "Accept-Language" : "zh-CN,en,*" , "Connection" : "close" , "Host" : "httpbin.org" , "User-Agent" : "Mozilla / 5.0 (Macintosh; Intel Mac OS X) AppleWebKit / 538.1 (KHTML, like Gecko) PhantomJS / 2.1 . 0 Safari / 538.1 " }, "origin" : "106.185.45.153" , "url" : "http://httpbin.org/get" } |
運行結果的 origin 同樣為代理的 IP,設置代理成功。
如果需要認證,那么只需要再加入 –proxy-auth 選項即可,這樣參數就改為:
1
2
3
4
5
|
service_args = [ '--proxy=127.0.0.1:9743' , '--proxy-type=http' , '--proxy-auth=username:password' ] |
將 username 和 password 替換為認證所需的用戶名和密碼即可。
5. 本節代碼
本節代碼地址為:https://github.com/Python3WebSpider/ProxySettings。
6. 結語
本節介紹了前文所介紹的請求庫的代理設置方法,稍作了解即可,后面我們會使用這些方法來搭建代理池和爬取網站,進一步加深印象。
原文鏈接:https://www.py.cn/spider/advanced/14436.html