分布式爬虫之python动态获取随机选择出口ip

这两天有几个朋友都在问我,你们爬虫的多ip方案是如何搞定的。  


其实我们的方案多元化的,根据历史遗留的问题,大部分是采用的分布式http代理的方式,也就是开了n个虚拟机,然后安装http代理的服务,以前是squid做正向代理.  因为squid代理专业是专业,但是不够轻型。So , 用twisted构建了一个高性能的http代理,他的优点是可控性好,我们可以在http代理服务商,在做一层逻辑,比如是过滤

后来,取消了分布式http代理,在nat的服务节点上,构建了对于出口的ip控制.   

现在我们的方式更加的简单,直接嵌入到代码里面,每个小时会自动切换ip   ….  多网卡或者是一个网卡多个子ip,这都是行的通的。 

这里就简单写下,如何让你的爬虫动态的选择出口ip…    


文章的源地址是

http://xiaorui.cc

http://xiaorui.cc

http://xiaorui.cc

http://xiaorui.cc


下面是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)


大家觉得文章对你有些作用! 如果想赏钱,可以用微信扫描下面的二维码,感谢!
另外再次标注博客原地址  xiaorui.cc

3 Responses

  1. 清风 2016年1月8日 / 下午3:56

    楼主,多线程的时候同时调用这个脚本是否可行,好像有点问题~

  2. 清风 2015年12月21日 / 下午4:40

    好东西,正好需要!

  3. python 2015年11月16日 / 下午11:47

    支持 难得的好文

清风进行回复 取消回复

邮箱地址不会被公开。 必填项已用*标注