码梦成真
2023/05/17阅读:17主题:全栈蓝
爬网站IP老是被封?代理IP太贵?如何利用Python爬取代理IP并检测代理IP是否可用?
前言
随着爬虫技术的不断发展,越来越多的网站开始采用反爬机制来防止爬虫的访问。如果我们直接使用本机 IP 去爬取这些网站的数据,很可能会被封禁,无法正常获取到所需的数据。
为了避免这种情况的发生,我们可以考虑使用代理 IP 去访问目标网站。代理 IP 是一种能够隐藏本机真实 IP 地址的技术,通过代理服务器进行访问,可以达到隐藏身份、绕过封禁等效果。
在这篇文章中,我将介绍如何使用 Python 爬取代理 IP,并检测代理 IP 是否可用。
一、爬取代理 IP
1.1 免费代理 IP 网站
首先,我们需要找到一些免费的代理 IP 网站来获取代理 IP。常见的代理 IP 网站有:
-
http://www.kuaidaili.com/ -
http://www.ip3366.net/ -
http://www.66ip.cn/
这些网站提供了大量的免费代理 IP,我们可以选择其中一个或多个网站进行爬取。
1.2 爬取代理 IP
下面以 http://www.66ip.cn/ 为例,演示如何爬取代理 IP。
def get_proxy():
"""
爬取代理IP网站并返回前三页的代理IP列表,每个元素为(protocol, ip)的形式
"""
url_template = 'http://www.66ip.cn/{}.html'
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'}
ip_list = []
for page in range(1, 4):
url = url_template.format(page)
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
for tr in soup.select('#main table tr')[1:]:
tds = tr.select('td')
ip = tds[0].text
port = tds[1].text
protocol = 'http'
ip_list.append((protocol, f'{ip}:{port}'))
return ip_list
以上代码中,我们通过 requests 库发送了一个 GET 请求获取目标网站的 HTML 页面,并使用 BeautifulSoup 库对页面进行解析。由于这个网站表格的每一行都包含了一个代理 IP 和端口号信息,我们可以遍历表格中的每一行,提取出 IP、端口号和协议类型等信息,将它们存储在一个列表中。
最后,我们将这个包含所有代理 IP 的列表打印出来,就可以看到我们成功地爬取到了多个代理 IP。
二、检测代理 IP 是否可用
爬取到代理 IP 之后,我们需要检测这些代理 IP 是否可用,如果有不可用的代理 IP,则需要将其过滤掉,以保证获取到的代理 IP 都是可用的。
2.1 检测代理 IP
我们可以使用 requests 库和检测网站(如百度)来检测代理 IP 是否可用。下面是一个检测代理 IP 的函数示例:
def check_proxy(proxy):
"""
检测代理IP是否可用,返回值为True或False
"""
try:
response = requests.get('http://icanhazip.com/', proxies={'http': proxy, 'https': proxy}, timeout=5)
if response.status_code == 200:
return True
else:
return False
except:
return False
在上述代码中,我们向一个检测网站(如百度)发送包含代理信息的请求,并指定用于该请求的代理 IP。如果请求成功返回响应状态码为 200,则代理 IP 可用,可以返回 True;否则,返回 False。同时,为了避免网络故障或代理服务器不稳定等问题导致的请求失败,使用了异常处理机制来捕获异常,并返回 False。
2.2 过滤不可用的代理 IP
有了检测代理 IP 的函数,我们就可以遍历上面爬取到的代理 IP 列表,并将不可用的代理 IP 过滤掉,只保留可用的代理 IP。下面是一个实现过滤不可用代理 IP 的函数示例:
available_list = []
for i, proxy in enumerate(ip_list):
if check_proxy(proxy[1]):
print(f'{i + 1}. {proxy[0]}://{proxy[1]} 可用')
available_list.append(proxy)
else:
print(f'{i + 1}. {proxy[0]}://{proxy[1]} 不可用')
print(f'共有{len(available_list)}个可用代理IP')
在上述代码中,我们遍历代理 IP 列表中的每一个元素,使用 check_proxy 函数检测该代理 IP 是否可用,如果可用则加入到 available_list 列表中,并返回该列表。
三、完整代码
import requests
from bs4 import BeautifulSoup
def get_proxy():
"""
爬取代理IP网站并返回前三页的代理IP列表,每个元素为(protocol, ip)的形式
"""
url_template = 'http://www.66ip.cn/{}.html'
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'}
ip_list = []
for page in range(1, 3):
url = url_template.format(page)
response = requests.get(url, headers=headers)
soup = BeautifulSoup(response.text, 'html.parser')
for tr in soup.select('#main table tr')[1:]:
tds = tr.select('td')
ip = tds[0].text
port = tds[1].text
protocol = 'http'
ip_list.append((protocol, f'{ip}:{port}'))
return ip_list
def check_proxy(proxy):
"""
检测代理IP是否可用,返回值为True或False
"""
try:
response = requests.get('http://icanhazip.com/', proxies={'http': proxy, 'https': proxy}, timeout=5)
if response.status_code == 200:
return True
else:
return False
except:
return False
if __name__ == '__main__':
# 爬取代理IP并检测可用性
ip_list = get_proxy()
print(f'共获取到{len(ip_list)}个代理IP')
available_list = []
for i, proxy in enumerate(ip_list):
if check_proxy(proxy[1]):
print(f'{i + 1}. {proxy[0]}://{proxy[1]} 可用')
available_list.append(proxy)
else:
print(f'{i + 1}. {proxy[0]}://{proxy[1]} 不可用')
print(f'共有{len(available_list)}个可用代理IP')
以上是完整的检测代理 IP 的 Python 代码,首先我们定义了一个 get_proxy 函数,用于爬取代理 IP 网站并返回代理 IP 列表。接着,我们定义了一个 check_proxy 函数,用于检测代理 IP 是否可用。
在主程序中,我们使用 get_proxy 获取代理 IP 列表,将不可用的代理 IP 过滤掉,只保留可用的代理 IP将可用的IP保存到available_list列表,并且统计打印输出可用代理 IP 的数量和各个代理 IP 的详细信息。
注意
❝这里的代理 IP 仅供学习使用,不得用于非法用途。若要实际爬取目标网站,请遵守相关法律法规,并尽量使用付费代理 IP 或者自建代理池等方式,以避免被封禁或其他问题。
❞
作者介绍