Python 爬蟲使用動(dòng)態(tài)切換ip防止封殺
上次有說過,我在新公司有部分工作是負(fù)責(zé)爬蟲業(yè)務(wù)的,爬蟲機(jī)器有上百臺,節(jié)點(diǎn)也要計(jì)劃遷入了Docker平臺上。 這兩天遇到一個(gè)棘手的問題,就是因?yàn)槲覀優(yōu)榱俗非髷?shù)據(jù)量,在某些機(jī)房,用docker啟動(dòng)了不少爬蟲節(jié)點(diǎn),導(dǎo)致一些傻逼網(wǎng)站,開始封禁我們…. … (干死他們,哥們要是有資源,必須干掉ddos,讓你防 ! 當(dāng)然我也就裝裝逼,沒這個(gè)資源)
對于爬蟲被封禁 ! 爬蟲一般來說只要你的ip夠多,是不容易被封的。 一些中小網(wǎng)站要封殺你,他的技術(shù)成本也是很高的,因?yàn)榇蠖鄶?shù)網(wǎng)站沒有vps,他們用的是虛擬空間或者是sae,bae這樣的paas云。 其實(shí)就算他們不考慮seo搜索優(yōu)化,用ajax渲染網(wǎng)頁數(shù)據(jù),我也可以用webkit瀏覽器組件來搞定ajax之后的數(shù)據(jù)。
如果某個(gè)網(wǎng)站他就是閑的蛋疼,他就是喜歡從log里面,一行行的分析出你的ip,然后統(tǒng)計(jì)處頻率高的網(wǎng)站, 那這個(gè)時(shí)候咋辦? 其實(shí)方法很草比,就是用大量的主機(jī),但是大量的主機(jī)是有了,你如果沒有那么爬蟲的種子量,那屬于浪費(fèi)資源… … 其實(shí)一個(gè)主機(jī),多個(gè)ip是可以的。。。
這個(gè)時(shí)候是有兩種方法可以解決的,第一個(gè)是用squid綁定多個(gè)ip地址,做正向代理…. 你的程序里面維持一組連接池,就是針對這幾個(gè)正向proxy做的連接池。
正向代理和反向代理最大的區(qū)別就是,反向代理很多時(shí)候域名是固定的,而正向代理是通過一個(gè)http的代理端口,隨意訪問,只是在proxy端會(huì)修改http協(xié)議,去幫你訪問
如果是python,其實(shí)單純調(diào)用socket bind綁定某個(gè)ip就可以了,但是標(biāo)題的輪訓(xùn)是個(gè)什么概念,就是維持不同的socket bind的對象,然后你就輪吧 ! 跟一些業(yè)界做專門做爬蟲的人聊過,他們用的基本都是這樣的技術(shù)。
# -*- coding=utf-8 -*-
import socket
import urllib2
import re
true_socket = socket.socket
ipbind='xx.xx.xxx.xx'
def bound_socket(*a, **k):
sock = true_socket(*a, **k)
sock.bind((ipbind, 0))
return sock
socket.socket = bound_socket
response = urllib2.urlopen('http://www.ip.cn')
html = response.read()
ip=re.search(r'code.(.*?)..code',html)
print ip.group(1)
在http://stackoverflow.com/ 上也找到一些個(gè)老外給與的解決方法的思路,他是借助于urllib2的HTTPHandler來構(gòu)造的出口的ip地址。
import functools
import httplib
import urllib2
class BoundHTTPHandler(urllib2.HTTPHandler):
def __init__(self, source_address=None, debuglevel=0):
urllib2.HTTPHandler.__init__(self, debuglevel)
self.http_class = functools.partial(httplib.HTTPConnection,
source_address=source_address)
def http_open(self, req):
return self.do_open(self.http_class, req)
handler = BoundHTTPHandler(source_address=("192.168.1.10", 0))
opener = urllib2.build_opener(handler)
urllib2.install_opener(opener)
import functools
import httplib
import urllib2
class BoundHTTPHandler(urllib2.HTTPHandler):
def __init__(self, source_address=None, debuglevel=0):
urllib2.HTTPHandler.__init__(self, debuglevel)
self.http_class = functools.partial(httplib.HTTPConnection,
source_address=source_address)
def http_open(self, req):
return self.do_open(self.http_class, req)
handler = BoundHTTPHandler(source_address=("192.168.1.10", 0))
opener = urllib2.build_opener(handler)
urllib2.install_opener(opener)
那么就有一個(gè)現(xiàn)成的模塊 netifaces ,其實(shí)netifaces模塊,就是剛才上面socket綁定ip的功能封裝罷了
地址: https://github.com/raphdg/netifaces
import netifaces
netifaces.interfaces()
netifaces.ifaddresses('lo0')
netifaces.AF_LINK
addrs = netifaces.ifaddresses('lo0')
addrs[netifaces.AF_INET]
[{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}]
import netifaces
netifaces.interfaces()
netifaces.ifaddresses('lo0')
netifaces.AF_LINK
addrs = netifaces.ifaddresses('lo0')
addrs[netifaces.AF_INET]
[{'peer': '127.0.0.1', 'netmask': '255.0.0.0', 'addr': '127.0.0.1'}]
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
版權(quán)聲明:本站文章來源標(biāo)注為YINGSOO的內(nèi)容版權(quán)均為本站所有,歡迎引用、轉(zhuǎn)載,請保持原文完整并注明來源及原文鏈接。禁止復(fù)制或仿造本網(wǎng)站,禁止在非maisonbaluchon.cn所屬的服務(wù)器上建立鏡像,否則將依法追究法律責(zé)任。本站部分內(nèi)容來源于網(wǎng)友推薦、互聯(lián)網(wǎng)收集整理而來,僅供學(xué)習(xí)參考,不代表本站立場,如有內(nèi)容涉嫌侵權(quán),請聯(lián)系alex-e#qq.com處理。
關(guān)注官方微信