这两天有几个朋友都在问我,你们爬虫的多ip方案是如何搞定的。
其实我们的方案多元化的,根据历史遗留的问题,大部分是采用的分布式http代理的方式,也就是开了n个虚拟机,然后安装http代理的服务,以前是squid做正向代理. 因为squid代理专业是专业,但是不够轻型。So , 用twisted构建了一个高性能的http代理,他的优点是可控性好,我们可以在http代理服务商,在做一层逻辑,比如是过滤
后来,取消了分布式http代理,在nat的服务节点上,构建了对于出口的ip控制.
现在我们的方式更加的简单,直接嵌入到代码里面,每个小时会自动切换ip …. 多网卡或者是一个网卡多个子ip,这都是行的通的。
这里就简单写下,如何让你的爬虫动态的选择出口ip…
文章的源地址是
下面是python requests 的实现方式,我相信对于数据的抓取用requests的要比urllib2多。
import socket real_create_conn = socket.create_connection def set_src_addr(*args): address, timeout = args[0], args[1] source_address = ('你需要绑定的ip地址', 0) return real_create_conn(address, timeout, source_address) socket.create_connection = set_src_addr import requests r = requests.get('http://ip.cn')
urllib2的实现的方式,这个方式更加的通用。。 。
# -*- 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)
不管是requests还是urllib2,他们的底层都是通过httplib这个模块实现的。
在python2.7的httplib源码中就有说明的.. source_address 这个就是你本地的某个ip地址。
class httplib.HTTPSConnection(host[, port[, key_file[, cert_file[, strict[, timeout[, source_address[, context]]]]]]])
我们会发现,其实真的很简单,他的原理其实很像squid做多ip正向代理,曾经抓过包分析过,对比过,基本一致的。
上面的两种方式更像是在httplib的层面加源地址,也就是bind ip ,如果做服务端的话,就用下面的方式…
s = socket.socket(socket.AF_INET,socket.SOCK_STREAM) s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) s.bind(("127.0.0.1",8099)) s.listen(5)
楼主,多线程的时候同时调用这个脚本是否可行,好像有点问题~
好东西,正好需要!
支持 难得的好文