写在前面
建立IP代理池可以有效避免IP被封锁或限制访问等问题。
下面是详细步骤和代码实现:
1. 获取代理IP
我们可以从一些代理IP网站上获取免费或付费的代理IP,或者自己租用代理IP服务。这里我们以站大爷代理为例,获取前10页的HTTP代理IP地址。
import requests from scrapy.selector import Selector def get_proxy_ips(): proxy_ips = [] for i in range(1, 11): url = 'https://www.zdaye.com/free/'.format(i) headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} res = requests.get(url, headers=headers) selector = Selector(text=res.text) trs = selector.css('#ip_list tr') for tr in trs[1:]: ip = tr.css('td:nth-child(2)::text').extract_first() port = tr.css('td:nth-child(3)::text').extract_first() proxy_ips.append('{}:{}'.format(ip, port)) return proxy_ips
2. 检测代理IP的可用性
获取到代理IP后,需要对其进行可用性的检测,筛选出可用性较高的IP地址。这里我们测试以百度为目标网站检测HTTP代理IP地址的可用性,如果响应码为200,则表明该IP地址可用。
import requests def check_proxy_ip(ip): url = 'http://www.baidu.com' headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} proxies = {'http': 'http://' + ip, 'https': 'https://' + ip} try: res = requests.get(url, headers=headers, proxies=proxies, timeout=10) if res.status_code == 200: return True else: return False except: return False
3. 将可用的代理IP存储到池中
将可用的代理IP存储到一个IP池中,根据需要可以设置IP池的容量和存储时间。这里我们将可用的IP地址存储到redis数据库中。
import redis def save_proxy_ips(): proxy_ips = get_proxy_ips() pool = redis.ConnectionPool(host='localhost', port=6379, db=0) r = redis.Redis(connection_pool=pool) for ip in proxy_ips: if check_proxy_ip(ip): r.sadd('proxy_ip_pool', ip)
4. 使用代理IP池
设置代理IP池,并在请求时随机选择一个可用的代理IP地址进行访问。这里我们使用requests库和random模块实现。
import requests import redis import random def get_my_ip(): url = 'http://httpbin.org/ip' res = requests.get(url) return res.json()['origin'] def get_random_proxy(): pool = redis.ConnectionPool(host='localhost', port=6379, db=0) r = redis.Redis(connection_pool=pool) ip = r.srandmember('proxy_ip_pool') return ip.decode('utf-8') # 随机选择代理IP进行访问 def crawl(url): proxy = {'http': 'http://'+get_random_proxy(), 'https': 'https://'+get_random_proxy()} headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} try: res = requests.get(url, headers=headers, proxies=proxy, timeout=10) if res.status_code == 200: return res.text else: return None except: return None
总结
需要注意的是,代理IP池的建立和使用需要注意IP的有效性和时效性,及时更新池中的IP地址,以保证代理IP的可用性。同时,在使用代理IP时需要遵守相关法律法规和网站的使用协议,不得用于非法活动。