文章目录
一、爬取代理IP网站中所有IP
目前寻找到3个成功率比较高的代理IP网站
-
https://hidemy.name/cn/proxy-list/?type=s#list (可能需要v-p-n)
-
http://www.xiladaili.com/https/(可能需要v-p-n)
1. 爬取第一个网站中所有的ip地址
import requests
from lxml import etree
# 定义一个全局数组,用了存放获取到的ip地址
list_ips = []
# 获取ip地址
def get_url(urls='https://hidemy.name/cn/proxy-list/?type=s#list'):
# 构建请求头
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36',
'cookie': '_ym_uid=1631777163767759683; _ym_d=1631777163; PAPVisitorId=b90c63abf5f4ae440925e5MpEdpDVCg3; PAPVisitorId=b90c63abf5f4ae440925e5MpEdpDVCg3; _ga=GA1.2.2061127712.1631777164; _gid=GA1.2.1247344787.1631777164; _ym_isad=2; _dc_gtm_UA-90263203-1=1; _gat_UA-90263203-1=1; _fbp=fb.1.1631777165623.195031136',
}
respons = requests.get(urls, headers=headers, )
# 获取请求内容,并且转换成html格式
html_content = etree.HTML(respons.content.decode('utf-8'))
tbody_list = html_content.xpath("//*[@class='table_block']/table/tbody/tr")
print(len(tbody_list))
# 如果能获取到数据,进行下一步
if len(tbody_list):
# 遍历内容
for tbody in tbody_list:
# 获取ip地址
ip_name = tbody.xpath('./td[1]/text()')[0]
# 获取端口号
port_name = tbody.xpath('./td[2]/text()')[0]
# 字符串拼接
ips = ip_name + ':' + port_name
# 添加到全局数组中
list_ips.append(ips)
else:
# 获取下一页url
next_url_xpath = html_content.xpath("//*[@class='next_array']/a/@href")
if len(next_url_xpath):
# 拼接下一页url
next_url = 'https://hidemy.name' + next_url_xpath[0]
# 继续请求
get_url(next_url)
else:
print('没有下一页了')
else:
print('没有获取到')
# 返回数据
return list_ips
# 调用方法
if __name__ == '__main__':
list_ip = get_url()
print(list_ip)
2. 爬取第二个网站中所有的ip地址
# 2.获取这的代理ip: http://www.xiladaili.com/https/
def get_https_ip(urls='http://www.xiladaili.com/https/'):
# 构建header
headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36',
'Cookie': 'Hm_lvt_9bfa8deaeafc6083c5e4683d7892f23d=1631780310; Hm_lpvt_9bfa8deaeafc6083c5e4683d7892f23d=1631780310',
}
# 发送请求
respons = requests.get(urls, headers=headers, )
# 延时2秒等待数据加载完成在获取
time.sleep(2)
# 获取内容,转换成html格式
html_content = etree.HTML(respons.content.decode('utf-8'))
# 读取内容
tbody_list = html_content.xpath("//*[@class='fl-table']/tbody/tr")
if len(tbody_list):
# 遍历内容
for tbody in tbody_list:
# 直接获取ip地址+端口号
ip_name = tbody.xpath('./td[1]/text()')[0]
# 添加到数组
list_ips.append(ip_name)
else:
# 获取下一页链接
next_url_xpath = html_content.xpath("//*[text()='下一页']/@href")
if len(next_url_xpath):
# 只提前30页ip,该网站一共有2000多页,我们只需要提前30页即可
if (next_url_xpath[0] == '/https/30/'):
print('到30页了')
return
# 拼接下一页地址
next_url = 'http://www.xiladaili.com' + next_url_xpath[0]
print(next_url)
# 递归调用自己
get_https_ip(next_url)
else:
print('没有下一页了')
else:
print('没获取到数据')
# 该网站存在,因为前30页数据中,某一页突然没数据,然后隔一页才有,因此在这需要再次获取下一页链接
next_url_xpath = html_content.xpath("//*[text()='下一页']/@href")
if len(next_url_xpath):
if (next_url_xpath[0] == '/https/30/'):
print('到100页了')
return
next_url = 'http://www.xiladaili.com' + next_url_xpath[0]
print(next_url)
get_https_ip(next_url)
else:
print('没有下一页了')
# 返回数据
return list_ips
# 调用方法
if __name__ == '__main__':
list_ip = get_https_ip()
print(list_ip)
3. 爬取第三个网站中所有的ip地址
第三个网站做了反爬措施!!!
用户打开以后不能复制,不能右键,端口号是图片组成
因此我们要获取图片,然后识别图片中的数字来获取端口号
3.1 通过图片url获取图片内容,并且识别图片中数字
# 头文件需要安装,同时还得需要安装tesseract,具体的可以参考百度!!!
import pytesseract
from PIL import Image
# 通过图片的url,下载图片到本地,然后在通过ocr进行识别,最后返回图片内容
def getImageWithocr(image_url):
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36',
'cookie': 'MIMVPSESSID=js2d5ibkumcpibthk64mmf85sa; Hm_lvt_51e3cc975b346e7705d8c255164036b3=1631607506,1631677690,1631849436; Hm_lpvt_51e3cc975b346e7705d8c255164036b3=1631858821',
}
responds = requests.get(image_url, headers=headers)
# 存储到本地port_image文件夹下面
with open("port_image/background_pic.png", "wb") as f:
f.write(responds.content)
try:
# 这里识别以后有可以把8识别成B,有可能有‘,’,因此需要转换!!!
text = pytesseract.image_to_string(Image.open('port_image/background_pic.png')).replace(',', '').replace('B',
'8')
# print(text)
except:
print('读取失败,没有找到图片')
# 最后返回图片内容
return text
3.2 爬取数据
# 接上面代码
# 因为免费用户只能查看第一页ip,所以不用翻页
def getProxyip(urls='https://proxy.mimvp.com/freeopen?proxy=in_hp&sort=&page=1'):
headers = {
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.82 Safari/537.36',
'cookie': 'MIMVPSESSID=2o7m730du3qm487gpjgh7cjmbc; Hm_lvt_51e3cc975b346e7705d8c255164036b3=1631860283; Hm_lpvt_51e3cc975b346e7705d8c255164036b3=1631860283',
}
responds = requests.get(urls, headers=headers)
html_content = etree.HTML(responds.content.decode('utf-8'))
allips = html_content.xpath("//*[@class='mimvp-tbl free-proxylist-tbl']/tbody/tr")
if len(allips):
for ip_name_item in allips:
# 获取ip地址
ip_name = ip_name_item.xpath('./td[2]/text()')[0]
# 获取端口号图片
image_url = 'https://proxy.mimvp.com' + ip_name_item.xpath('./td[3]/img/@src')[0]
# 识别出端口号
port_name = getImageWithocr(image_url)
# 拼接地址
ips = ip_name + ':' + port_name.replace('\n', '').replace('\x0c', '')
# 添加数据
list_ips.append(ips)
else:
print('没有获取到ip地址')
return list_ips
# 调用方法
if __name__ == '__main__':
list_ip = getProxyip()
print(list_ip)
二、检测可用代理IP
1. 检测原理
检测原理:通过代理IP访问https://www.baidu.com
如果能够访问说明代理IP可以使用,否则不能使用
2. 检测代码
代码如下:
import requests
import threading
# test_csd.py 就是上一步获取所有代理ip的文件,通过导入这个文件可以直接调用内部方法,得到代理ip的数组
import test_csd
def jc_net(ips):
'''
# 设置代理,此处需要注意一下
# 有的是需要 {'https': 'https://+'ips}, urllib版本号不同设置代理方式不同,我的是1.22
'''
proxy = {'https': ips}
# 以百度为例
url = 'https://www.baidu.com'
# 构建header
head = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.102 Safari/537.36',
'Connection': 'keep-alive'}
try:
# 用代理请求百度,设置超时时间20秒
response = requests.get(url, proxies=proxy, headers=head, timeout=20)
except (requests.exceptions.ConnectTimeout, requests.exceptions.ProxyError, requests.exceptions.SSLError,
requests.exceptions.ConnectionError) as e:
# 捕获异常,此处说明代理不可用!!
print("443失败", ips)
else:
# 此处说明代理可用
# 有需要的可以把可用代理添加到数组中,或者执行其他任务
# 以本代码为例:
# 1.获取当前目录下所有的log文件
log_list = file_name('./')
# 2.把当前可用的代理ip转换成'123_345_793_8080.log'形式,用来当做log日志
str_ip_log = ips.replace('.', '_').replace(':', '_') + '.log'
# 3.遍历一下当前目录所有的log文件
for logs in log_list:
# 如果有相同的,说明执行过这个任务,就不必要再次执行了
if str_ip_log == logs:
print('有一样的,这个IP不符合', logs)
return
else:
# 此处是可以执行的ip
print('可以执行的IP', ips, response.status_code)
# 终端后台执行任务,并把日志文件以代理ip的形式输出 csdn_request3.py文件就是刷博客的文件
ml = 'nohup python3 -u csdn_request3.py %s > %s 2>&1 &' % (ips, str_ip_log)
os.system(ml)
# 获取当前目录下所有的.log文件
def file_name(file_dir):
L = []
for root, dirs, files in os.walk(file_dir):
for file in files:
if os.path.splitext(file)[1] == '.log':
L.append(file)
return L
# 程序运行
if __name__ == '__main__':
# 1.get_url 2.get_https_ip 3.getProxyip
# 只有要调用1 ,2 ,3的方法就能得到ip的数组
list_ip = test_csd.get_url()
# 遍历数组
for ips in list_ip:
# 用多线程方式执行效率比较高
sub_thread = threading.Thread(target=jc_net, args=(ips,))
sub_thread.start()