python 反爬總結(1)- 限制IP UA 的解決方法,修改headers和新增IP代理池
阿新 • • 發佈:2018-12-06
在學習python爬蟲的過程中,遇到各種反爬機制,個人總結了一下:
對同樣的ip或User-Agent進行限制,
對頻繁訪問的ip進行限制,
設定登陸限制,
設定驗證碼,
設定Ajax載入頁面。
目前小白我也就瞭解這麼多,其中驗證碼的反反爬還在學習當中,學無止境啊
第一篇就說點簡單的。
如果遇到前兩種,還是比較好解決的。
遇到對User-Agent進行限制的,可以在程式碼中修改請求頭,即
headers = { "User-Agent": "Mozilla/5.0 (Windows; U; Windows NT 6.1; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50" }
寫入Request中就可以了,推薦個網站,裡面的常用的User-Agent比較全,提示!提示!提示!網站中的那一行行裡面前面的user-agent是不需要的,只要後面的。
http://www.jsons.cn/useragent/
對於限制ip的,第一,可以自己整一個代理ip嘗試,這種也是成功一時的方法,長久參考,設定一個代理池是比較妥當的方法。
在scrapy框架中,代理池可以設定在settings裡面,也可以設定在 中介軟體Middlewares.py中,這裡就說一下在中介軟體Middlewares
中設定代理池吧,上程式碼
# 首先,這是自己能夠找到ip的時候,可以整個列表,然後寫個隨機函式隨機取一個 import random PROXIES = ['http://183.207.95.27:80', 'http://111.6.100.99:80'] class ProxyMiddleware(object): ''' 設定Proxy ''' def process_request(self, request, spider): ip = random.choice(PROXIES) request.meta['proxy'] = ip
# 還有就是可以去一些專門做代理服務的網站購買代理池,我是在阿布雲上購買的, import base64 proxyServer = "http://proxy.abuyun.com:9020" #new proxyUser = "***************" #購買之後給的祕鑰輸入進去 proxyPass = "***************" proxyAuth = "Basic " + str(base64.encodebytes(bytes(proxyUser + ":" + proxyPass, 'utf-8')), 'utf-8').strip() class ProxyMiddleware(object): def process_request(self, request, spider): print("=============abuyun ==============", request.url) request.meta["proxy"] = proxyServer request.headers["Proxy-Authorization"] = proxyAuth
在這裡補全一個使用自己爬取到的一些代理做的ip池,可以迴圈的取出準備的ip,並且把不能用的ip刪除掉。
# ip代理
class ProxyMiddleware(object):
def __init__(self):
self.ip_pool = self.get_ip()
def get_ip(self):
return [
'182.18.6.9:53281',
'118.212.95.34:53281',
'114.91.164.97:9999',
'222.170.0.102:53281',
'120.92.74.189:3128',
'183.129.207.73:14823',
'124.204.78.12:8123',
]
def process_request(self, request, spider):
# 隨機一個代理
self.ip = random.choice(self.ip_pool)
print('*' * 100)
print('現在使用的代理是--%s--' % self.ip)
print('*' * 100)
request.meta['proxy'] = 'http://' + self.ip
request.meta['download_timeout'] = 5
# 代理伺服器連線失敗,丟擲異常,就會走這裡
def process_exception(self, request, exception, spider):
print('*' * 100)
print(exception)
print('*' * 100)
# 幹掉這個不可用的代理
self.ip_pool.remove(self.ip)
if len(self.ip_pool) < 2:
self.ip_pool = self.get_ip()
# 請求需要重寫傳送
return request