使用代理繞過網站的反爬機制

最近在嘗試收集一些網絡指標的數據, 所以, 我又開始做爬蟲了。 :)

我們在做爬蟲的過程中經常會遇到這樣的情況,最初爬蟲正常運行,正常抓取數據,一切看起來都是那麼的美好,然而一杯茶的功夫可能就會出現錯誤,比如 403 Forbidden,這時候打開網頁一看,可能會看到 “您的 IP 訪問頻率太高” 這樣的提示,或者跳出一個驗證碼讓我們輸入,輸入之後纔可能解封,但是輸入之後過一會兒就又這樣了。

出現這樣的現象的原因是網站採取了一些反爬蟲的措施,比如服務器會檢測某個 IP 在單位時間內的請求次數,如果超過了這個閾值,那麼會直接拒絕服務,返回一些錯誤信息,這種情況可以稱之爲封 IP,於是乎就成功把我們的爬蟲禁掉了。

既然服務器檢測的是某個 IP 單位時間的請求次數,那麼我們藉助某種方式來僞裝我們的 IP,讓服務器識別不出是由我們本機發起的請求,不就可以成功防止封 IP 了嗎?

所以這時候代理就派上用場了。本章會詳細介紹代理的基本知識及各種代理的使用方式,包括代理的設置、代理池的維護、付費代理的使用、ADSL 撥號代理的搭建方法等內容,以幫助爬蟲脫離封 IP 的 “苦海”。

獲取代理

在做測試之前, 我們需要先獲取一個可用代理。搜索引擎搜索 “代理” 關鍵字,就可以看到許多代理服務網站,網站上會有很多免費代理, 大部分免費的代理都不好用, 我也想過從一些發佈免費代理的網頁上採集代理的地址, 哎, 就這事, 就花了兩天時間, 很多時候, 採集來的代理基本上沒法用, 採集了幾百個, 最後自檢的時候, 就剩下不到20個alive的。

後來找到一個付費的代理, 當然付費代理就好用很多, 常用的付費代理, 我就不一一介紹了, 由於我是採集海外的資源, 所以根據一些論壇的推薦, 找到了 這家, 我也順便發個aff, 介意勿點。

Socks5.io 海外IP代理

Edit description

my.socks5.io

爲什麼推薦這個, 是因爲這家讓我意外的發現他們家的免費代理也很好用, 不盡快, 還能保證很高的可用性。 來看看這個免費的offer, 0元購

看到沒, 說實話, 我現在在做的事情, 包括這篇文章, 就是爲了拿到第三個offer。 Anyway, 我們先註冊一個賬號, 可以先免費使用部分代理, 然後我們使用代理池來確保我們的python 爬蟲, 可以批量的添加代理, 或者隨機選擇代理。

我們先選擇免費動態ip代理, 然後可以提取最多100個ip, 剩下就生成API 提取就可以了。 比忘記把你自己的公網地址放到白名單裏。 然後生成的url可以直接用瀏覽器打開, 就可以看到是這樣格式的代理地址列表

隨便測試一個都可以用。

使用 requests 來隨機選擇代理訪問

對於 requests 來說,代理設置更加簡單,我們只需要傳入 proxies 參數即可。

還是以上例中的代理爲例,我們來看下 requests 的代理的設置:

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)

 

那麼結合我們可以每隔一段時間更新一下代理的話, 那麼我們可以這樣寫:

proxies = []
current_proxy = 0
token = 'xxxxxx' #生成api裏的token字段

def get_proxy():
    global proxies
    url = 'http://api.socks5.io/user_get_ip_list?token={token}&type=dc&qty=100&country=&time=5&format=txt&filter=1'
    r = requests.get(url)
    if r.status_code == 200:
        proxies = r.text.split('\n')
    else:
        print('error in get_proxy')

 



# 每次獲取一個代理
def get_one_proxy():
    if len(proxies) == 0:
        get_proxy()
    global current_proxy
    p = proxies[current_proxy]
    if current_proxy == len(proxies) - 1:
        current_proxy = 0
    if p is not None and p.strip() != '':
        current_proxy += 1
        return p
    else:
        return get_one_proxy()

def test_proxy():
    url = 'https://baidu.com'
    headers = {
        'User-Agent': 'customized ua -- 1.0',
        'X-Requested-With': 'XMLHttpRequest',
    }
    try:
        p = get_one_proxy()
        r = requests.get(url, headers=headers, timeout=5, proxies={'http': f'http://{p}'})
        if r.status_code == 200:
            # process html data from r.text
            with open(filename, 'w') as f:
                f.write(r.text)
                retry = 0
            return r.text
        else:
            print(f'Error: {r.status_code}')
            retry = 0
            return ''

 

 

這樣就可以每次更換一個代理的地址來爬網頁了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章