Python实现高效代理IP抓取与可用性检测
本文分享使用Python获取并验证免费代理IP的完整流程。通过正则表达式从西刺代理网站抓取IP及端口,利用多线程机制并行检测IP可用性,最终返回格式化的可用IP列表。代码包含getIP、check_one及mul_thread_check三个核心函数,适用于需要规避同一IP重复访问限制的数据抓取场景。
在进行数据爬取时,许多网站会限制同一IP的频繁访问。为规避此类限制,我们需要使用代理IP,在每次请求前进行伪装,从而隐藏真实身份,避免被目标网站识别和封锁。
接下来,我们将直接进入代码实现环节。
为了便于维护和复用,我将获取代理IP的功能模块化,拆分为三个独立的函数。
注:代码中包含部分英文注释,旨在简化书写过程,通常简短的英文单词即可清晰表达逻辑。
#!/usr/bin/python
#-*- coding:utf-8 -*-
"""
author:dasuda
"""
import urllib2
import re
import socket
import threading
findIP = [] #获取的原始IP数据
IP_data = [] #拼接端口后的IP数据
IP_data_checked = [] #检查可用性后的IP数据
findPORT = [] #IP对应的端口
available_table = [] #可用IP的索引
def getIP(url_target):
patternIP = re.compile(r'(?<=<td>)[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}')
patternPORT = re.compile(r'(?<=<td>)[\d]{2,5}(?=</td>)')
print "now,start to refresh proxy IP..."
for page in range(1,4):
url = 'http://www.xicidaili.com/nn/'+str(page)
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64)"}
request = urllib2.Request(url=url, headers=headers)
response = urllib2.urlopen(request)
content = response.read()
findIP = re.findall(patternIP,str(content))
findPORT = re.findall(patternPORT,str(content))
#assemble the ip and port
for i in range(len(findIP)):
findIP[i] = findIP[i] + ":" + findPORT[i]
IP_data.extend(findIP)
print('get page', page)
print "refresh done!!!"
#use multithreading
mul_thread_check(url_target)
return IP_data_checked
def check_one(url_check,i):
#get lock
lock = threading.Lock()
#setting timeout
socket.setdefaulttimeout(8)
try:
ppp = {"http":IP_data[i]}
proxy_support = urllib2.ProxyHandler(ppp)
openercheck = urllib2.build_opener(proxy_support)
urllib2.install_opener(openercheck)
request = urllib2.Request(url_check)
request.add_header('User-Agent',"Mozilla/5.0 (Windows NT 10.0; WOW64)")
html = urllib2.urlopen(request).read()
lock.acquire()
print(IP_data[i],'is OK')
#get available ip index
available_table.append(i)
lock.release()
except Exception as e:
lock.acquire()
print('error')
lock.release()
def mul_thread_check(url_mul_check):
threads = []
for i in range(len(IP_data)):
#creat thread...
thread = threading.Thread(target=check_one, args=[url_mul_check,i,])
threads.append(thread)
thread.start()
print "new thread start",i
for thread in threads:
thread.join()
#get the IP_data_checked[]
for error_cnt in range(len(available_table)):
aseemble_ip = {'http': IP_data[available_table[error_cnt]]}
IP_data_checked.append(aseemble_ip)
print "available proxy ip:",len(available_table)
一、getIP(url_target):核心抓取函数。该函数接收一个用于验证代理IP有效性的目标网址作为参数,推荐使用ipchina进行验证。
我们从http://www.xicidaili.com/nn/网站获取免费代理IP。该网站提供大量免费IP,但可用性参差不齐。结合地理位置、网络环境及目标服务器状况,实际可用的IP比例通常不足20%,这在我的测试中也是常见情况。
通过正常方式访问http://www.xicidaili.com/nn/,获取网页源码后,利用正则表达式提取所需的IP地址和对应端口。具体代码实现如下:
patternIP = re.compile(r'(?<=<td>)[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}\.[\d]{1,3}')
patternPORT = re.compile(r'(?<=<td>)[\d]{2,5}(?=</td>)')
...
findIP = re.findall(patternIP,str(content))
findPORT = re.findall(patternPORT,str(content))
关于正则表达式的构建技巧,可参考其他相关技术文章。
提取到的IP地址存储在findIP列表中,对应的端口号存储在findPORT列表中,两者通过索引一一对应。通常情况下,每页获取的IP数量约为100个。
随后,将获取到的IP地址与端口号进行拼接,形成完整的代理地址字符串。
最后一步是对拼接后的IP进行可用性检查,确保其真实有效。
二、check_one(url_check, i):单线程检查函数。
该函数通过正常方式访问指定的url_check。若服务器返回响应,则判定该代理IP可用,并记录当前IP在列表中的索引值,以便后续提取所有可用IP。
三、mul_thread_check(url_mul_check):多线程并发检查。
此函数启动多线程机制对代理IP进行批量可用性检测,每个IP分配一个独立线程进行检查,以提高效率。
直接调用getIP()函数,并传入用于检查可用性的网址,即可返回一个列表。该列表包含经过可用性验证的IP,格式为字典形式的{'http': 'ip:port'}。
['ip1:port1','ip2:port2',....]
以上即为Python获取代理IP的完整实例分享,希望能对读者有所帮助,欢迎支持本站更多内容。
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









