代理的基本原理 及用Xpath爬取代理网站IP列表 测试并存入数据库

news/2024/5/12 9:55:09/文章来源:https://blog.csdn.net/Yy_Rose/article/details/122333506

 前言

        在网络爬虫中,有些网站会设置反爬虫措施,服务器会检测某个IP在单位时间内的请求次数,如果超过了这个阈值,就会直接拒绝服务,返回一些错误信息,例如 403 Forbidden,“您的IP访问频率过高”这样的提示,这就是IP被封禁了,这种情况下就需要进行IP伪装。

代理的基本原理

        代理实际上指的是代理服务器(proxy server),它的功能是代理网络用户去去的网络信息,是网络信息的中转站,一般情况下,请求访问网站时,是先发送请求给Web服务器,Web服务器再把响应传回给我们,如下图:

        如果设置了代理服务器,实际上是在本机和服务器之间建立了一个桥梁,此时本机不是直接向Web服务器发起请求,而是向代理服务器发出请求,请求会发送给代理服务器,然后由代理服务器再发送给Web服务器,接着由代理服务器再把Web服务器返回的响应转发给本机,图解如下,这样同样可以正常访问网页,但这个过程中Web服务器识别出的真实IP就不再是我们本机的IP了,就成功实现了IP伪装,这就是代理的基本原理。 

代理的作用 

  • 突破自身IP访问限制,访问一些平时不能访问的站点
  • 访问一些单位或团体内部资源
  • 提高访问速度:通常代理服务器都设置一个较大的硬盘缓冲区,当有外界信息通过时,同时也将其保存到缓冲区中,当其他用户再访问相同的信息时,则直接由缓冲区中取出信息,传给用户,以提高访问速度
  • 隐藏真实IP,当作防火墙保护自身网络安全,在爬虫中可以防止自身的IP被封锁 

代理分类 

1. 根据协议区分 

  • FTP 代理服务器:主要用于访问FTP服务器,一般有上传、下载以及缓存功能,端口一般为 21、2121等
  • HTTP 代理服务器:主要用于访问网页,一般有内容过滤和缓存功能,端口一般为 80、8080、3128等
  • SSL/TLS 代理:主要用于访问加密网站,一般有 SSL 或 TLS 加密功能(最高支持128位加密强度),端口一般为 443
  • RTSP 代理:主要用于访问Real流媒体服务器,一般有缓存功能,端口一般为 554
  • Telnet 代理:主要用于 telnet 远程控制(黑客入侵计算机时常用于隐藏身份),端口一般为 23
  • POP3/SMTP 代理:主要用于 POP3/SMTP 方式收发右键,一般有缓存功能,端口一般为 110/25
  • SOCKS 代理:只是单纯传递数据包,不关心具体协议和用法,所以速度很快,一般有缓存功能,端口一般为 1080 。SOCKS 代理协议又分为 SOCK4 和 SOCK5,SOCK4 只支持TCP,而后者支持 TCP 和 UDP,还支持各种身份验证机制、服务器端域名解析等。

2. 根据匿名程度区分

  • 高度匿名代理:会将数据包原封不动的转发,在服务端看来就好像真的是一个普通客户端在访问,而记录的IP是代理服务器的IP
  • 普通匿名代理:会在数据包上做一些改动,服务端上有可能发现这是个代理服务器,也有一定几率追查到客户端的真实IP。代理服务器通常会加入的HTTP头有 HTTP_VIA 和  HTTP_X_FORWORD_FOR
  • 透明代理:不但改动了数据包,还会告诉服务器客户端的真实IP。这种代理除了能用缓存技术提高浏览速度,能用内容过滤提高安全性之外,并无其他显著作用,最常见的例子是内网中的硬件防火墙
  • 间谍代理:指组织或个人创建的用于记录用户传输的数据,然后进行研究、监控等目的的地理服务器

常见代理设置

  • 使用网上的免费代理:最好使用高匿代理,这里将在下面爬取代理网站中所有代理
  • 使用付费代理服务:付费代理会比免费代理更为稳定,效果更好,按需求选择
  • ADSL 拨号:拨一次号换一次 IP,稳定性高

爬取代理网站IP

1. 定位所需网页元素节点,获取内容

        以云代理网站为例,网站地址:云代理 - 高品质http代理ip供应平台/每天分享大量免费代理IP

        这里我选择的是用Xpath解析库进行匹配爬取,在使用之前,需要确保安装好了 lxml 库,lxml 是 Python 的一个解析库,支持 HTML 和 XML 解析,支持 Xpath 解析方式,而且解析效率非常高,安装方式为:

pip3 install lxml

        如果没报错,则安装成功,若出现报错,例如缺少 libxml2 库等信息,可以采用 wheel 方式安装,推荐链接:https://www.lfd.uci.edu/~gohlke/pythonlibs/#lxml,下载对应的 wheel 文件,找到本地安装 Python 版本和系统对应的 lxml 版本,例如 Windows 64 位、python 3.6,就选择如下方式下载到本地:

pip3 install lxml-3.8.0-cp36-cp36m-win_amd64.whl

        如图可以看出,我们所需要的信息全都在 <tr> 标签中的 <td> 里,这就能写出 Xpath 表达式:

# 将 html 字符串转换为 _ELEMENT 对象
html = etree.HTML(html)
result = html.xpath("//div[@id='list']//tr/td/text()")

        可以通过浏览器插件 Xpath Helper 来验证是否正确,相关插件的安装及使用方式,可以参考博文:

selenium中如何配置使用浏览器插件 及 xpath-helper、chropath下载方式_Yy_Rose的博客-CSDN博客_xpath 插件

2. 连接 MySQL 数据库,创建表格

import pymysql# 获取数据库连接
db = pymysql.connect(host='localhost', user='root', passwd='123456', port=3306, db='proxy')
# 获取游标
cursor = db.cursor()
# 若无 proxy 数据库可执行如下操作
# cursor.execute("create database proxy default character set utf8")
# 删除之前创建的表格,不然新的数据会直接添加在旧数据之后,造成数据冗余
cursor.execute("drop table proxy_pool")
create_sql = "create table if not exists proxy_pool(" \"代理IP地址 varchar(255) not null," \"端口 int not null," \"匿名度 text not null," \"类型 varchar(255) not null," \"支持 varchar(255) not null," \"位置 text not null," \"响应速度 text not null," \"最后验证时间 varchar(255) not null)engine=innodb default charset=utf8;"
cursor.execute(create_sql)

3. 写入本地 txt

proxy_dir = 'proxy_pool.txt'
# 以追加模式写入
with open(proxy_dir, 'a', encoding='utf-8') as f:# json.dumps序列化时对中文默认使用的ascii编码,想输出真正的中文需要指定ensure_ascii=Falsef.write(json.dumps(content, ensure_ascii=False) + '\n')

4. 测试获取到的IP是否可用 

         代理IP样式为:代理IP地址 :端口,所以需要先获取相关内容,存入标准代理样式列表:

ip_and_port.append(proxy_infos[0].text.strip() + ':' + proxy_infos[1].text.strip())

        以请求访问百度为例,传入获取到的代理IP,若网站返回状态码为 200 则说明此代理IP有效,将有效的代理IP存入相应的可用代理列表中并输出显示,若出现其他情况则判断该代理IP无效,并显示该代理IP。

def ip_test(ip_and_port_list, usable_ip_list):url = "https://www.baidu.com/"try:for ip in ip_and_port_list:try:response = requests.get(url, proxy={'https': ip},headers=headers, timeout=0.5)if response.status_code == 200:usable_ip_list.append(ip)print("该代理ip有效:" + ip)else:print("该代理ip无效:" + ip)except:print("该代理ip无效:" + ip)except:return None

 完整代码

# @Author : Yy_Rose
import requests
from lxml import etree
import json
from requests.exceptions import RequestException
import time
import pymysql# 获取数据库连接
db = pymysql.connect(host='localhost', user='root', passwd='123456', port=3306, db='proxy')
# 获取游标
cursor = db.cursor()
# 若无 proxy 数据库可执行如下操作
# cursor.execute("create database proxy default character set utf8")
# 删除之前创建的表格,不然新的数据会直接添加在旧数据之后,造成数据冗余
cursor.execute("drop table proxy_pool")
create_sql = "create table if not exists proxy_pool(" \"代理IP地址 varchar(255) not null," \"端口 int not null," \"匿名度 text not null," \"类型 varchar(255) not null," \"支持 varchar(255) not null," \"位置 text not null," \"响应速度 text not null," \"最后验证时间 varchar(255) not null)engine=innodb default charset=utf8;"
# 执行数据库操作
cursor.execute(create_sql)# 构建请求头
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64)'' AppleWebKit/537.36 (KHTML, like Gecko)'' Chrome/86.0.4240.198 Safari/537.36','Cookie': 'Hm_lvt_c4dd741ab3585e047d56cf99ebbbe102=1640671968,''1641362375;'' Hm_lpvt_c4dd741ab3585e047d56cf99ebbbe102=1641362386'
}# 获取 HTTPResponse 类型的对象
def get_one_page(url):try:response = requests.get(url, headers=headers)if response.status_code == 200:# 编码response.encoding = 'gbk'return response.textreturn Noneexcept RequestException:return None# 解析获取内容
def parse_one_page(proxy_pool, html, ip_and_port):# 将 html 字符串转换为 _ELEMENT 对象content = etree.HTML(html)# 第一行为 th 标签内容,故从第二行开始tr_cnotent_list = content.xpath("//div[@id='list']//tr")[1:]for proxy_infos in tr_cnotent_list:# strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列proxy_pool.append([proxy_infos[0].text.strip(),proxy_infos[1].text.strip(),proxy_infos[2].text.strip(),proxy_infos[3].text.strip(),proxy_infos[4].text.strip(),proxy_infos[5].text.strip(),proxy_infos[6].text.strip(),proxy_infos[7].text.strip()])ip_and_port.append(proxy_infos[0].text.strip() + ':' + proxy_infos[1].text.strip())ip = proxy_infos[0].text.strip()port = proxy_infos[1].text.strip()anonymity = proxy_infos[2].text.strip()ip_type = proxy_infos[3].text.strip()support_type = proxy_infos[4].text.strip()position = proxy_infos[5].text.strip()response_speed = proxy_infos[6].text.strip()verify_time = proxy_infos[7].text.strip()# 将获取到的数据插入到数据库中insert_into = ("INSERT INTO proxy_pool(代理IP地址,端口,匿名度,类型,支持,位置,响应速度,最后验证时间)""VALUES(%s,%s,%s,%s,%s,%s,%s,%s);")data_into = (ip, port, anonymity, ip_type, support_type, position,response_speed,verify_time)cursor.execute(insert_into, data_into)# 将 insert 语句提交给数据库db.commit()# 写入本地 txt
def wirte_to_txt(content):proxy_dir = 'proxy_pool.txt'# 以追加模式写入with open(proxy_dir, 'a', encoding='utf-8') as f:# json.dumps序列化时对中文默认使用的ascii编码,想输出真正的中文需要指定ensure_ascii=Falsef.write(json.dumps(content, ensure_ascii=False) + '\n')# 打印内容到控制台
def print_list(proxy_list):for i in range(10):print(proxy_list[i])wirte_to_txt(proxy_list[i])# 测试IP是否可用
def ip_test(ip_and_port_list, usable_ip_list):url = "https://www.baidu.com/"try:for ip in ip_and_port_list:try:response = requests.get(url, proxy={'https': ip},headers=headers, timeout=0.5)if response.status_code == 200:usable_ip_list.append(ip)print("该代理ip有效:" + ip)else:print("该代理ip无效:" + ip)except:print("该代理ip无效:" + ip)except:return Nonedef main(offset):# 分页爬取url = 'http://www.ip3366.net/?stype=1&page=' + str(offset)html = get_one_page(url)proxy_pool = []usable_ip = []ip_port = []parse_one_page(proxy_pool, html, ip_port)print("以下为查询到的数据:")print_list(proxy_pool)print('=' * 50)ip_test(ip_port, usable_ip)print('=' * 50)print("有效的代理ip为:")# 判断列表是否为空if usable_ip:for usable in usable_ip:print(usable, end=' ')else:print(f"很遗憾,第{offset}页的代理IP全都无效")print('=' * 50)if __name__ == '__main__':num = int(input("请输出想查询多少页ip:"))# 共10页,100条记录,range()为左闭右开for page in range(1, num + 1):main(offset=page)time.sleep(2)

控制台打印: 

代理IP测试: 

本地 txt:

数据库效果:

写项目过程中的报错

pymysql.err.ProgrammingError: (1064, "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'get/post支持 varchar(255) not null,位置 text not null,响应速度 text not ' at line 1")

原因:创建表格的字段名与MySQL关键字冲突,get/post 支持改为支持即可

TypeError: not all arguments converted during string formatting

原因:并非所有参数都在字符串格式化期间转换

insert_into = ("INSERT INTO proxy_pool(代理IP地址,端口,匿名度,类型,支持,位置,响应速度,最后验证时间)""VALUES(?,?,?,?,?,?,?,?);")

分析可能性一:

        一开始使用的是 ?占位符, 其可使用参数的位置,标识变量,用于变量传值,支持和最后验证时间列不止一个元素,?无法完全匹配,导致参数数量不对应

        更改为 %s 就好了,%s 表示 str(),字符串可以包含空格、特殊字符,能一一匹配到完整元素

insert_into = ("INSERT INTO proxy_pool(代理IP地址,端口,匿名度,类型,支持,位置,响应速度,最后验证时间)""VALUES(%s,%s,%s,%s,%s,%s,%s,%s);")

分析可能性二:

import sqlite3

在SQLite数据库中,可以直接使用第一种方法插入一条或多条数据,经测试成功插入

import pymysql

在MySQL数据库中,不支持第一种插入方法

pymysql.err.InterfaceError: (0, '')

原因:数据库连接在创建表格后就关闭了,导致无法进行数据库操作,插入数据操作时报错

pymysql.err.DataError: (1366, "Incorrect string value: '\\xE9\\xAB\\x98\\xE5\\x8C\\xBF...' for column '匿名度' at row 1")

原因:创建数据库时未将字符集设置为 utf-8 格式,更改为 utf8 -- UTF-8 Unicode 即可,以下为之前导致报错的样式:

总结 

        免费的代理 IP 大部分都是无效的,不稳定的,以上为代理的相关知识及如何爬取代理网站代理 IP 列表的相关介绍,欢迎评论指正交流~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_903086.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring boot + vue 项目答辩 论坛网站(开源带前端)

这个项目素材源于网络如有侵权请联系删除 数据库前端 评论给 没事干发出来一起改进一下 项目论坛网站&#xff08;只推荐不讲解项目背景&#xff09; 一前台 1.1用户登录注册页面&#xff08;一个滑动效果&#xff09; 1.2找回密码 这里实现了一个发送邮箱验证码 1.3用户首页 …

hexo+github搭建个人博客网站问题汇总和解决办法

分享B站教程&#xff1a;【2021最新版】保姆级Hexogithub搭建个人博客_哔哩哔哩_bilibili 本人在使用hexo github搭建个人博客网站的过程中也是一步一个bug做过来&#xff0c;几乎每一步都有error&#xff0c;一路修复&#xff0c;在最后换主题的那一步始终都无法同步本地的c…

scrapy两种方法爬取网站小说

第一种&#xff0c;使用spider爬取 首先选择一个初始的小说链接&#xff0c;例如小说第一章的链接https://www.zwdu.com/book/11029/2297440.html 我爬去的是这个网站&#xff0c;链接中的小说 首先&#xff0c;创建一个项目 scrapy startproject novel 创建spider scrapy ge…

rhce:网络服务部分(三)给openlab搭建web网站

网站配置要求&#xff1a; 1.基于域名www.openlab.com可以访问网站内容为 welcome to openlab!!! 2.给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料和缴费网站&#xff0c;基于www.openlab.com/student 网站访问学生信息&#xff0c;www.openlab.com/data网站访…

linux中搭建基于http协议静态网站

目录 一、搭建静态网站——基于http协议的静态网站 1.安装httpd&#xff0c;并将访问apache服务器的首页修改为hello.html, 且内容为: "My Home Page is hello" 2.虚拟主机&#xff1a;虚拟两台主机ip为100,200, 对应访问目录&#xff1a;/www/ip/100, /www/ip/200…

SERVLET+JSP实现网站登录和注册(初)

SERVLET 使用10.0tomcat导入SERVLET得用tomcat/lib里的servlet-api.jar <url-pattern>/myServlet</url-pattern> 拼接到 http://ip:port/工程路径即http://ip:port/工程路径/myServletjspservlet实现login和register 能传回来数据&#xff0c;login和regiser网页…

为openlab搭建web网站

准备工作 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 [rootlocalhost ~]# yum install mod_ssl -y [rootlocalhost ~]# yum install httpd -y 一、基于域名www.openlab.com可以访问网站内容为welcome to openlab!!! 写入welcome to open…

网站基本配置表

网站的基本配置表 网站的基本参数 这些数据&#xff0c;不要单独放在各个表中&#xff0c; 要把所有参数放在网站中config表中&#xff0c;为网站运行的基本参数表

生成随机头像的网站

https://joeschmoe.io/api/v1/ 该网站为生成随机头像的网站 使用说明&#xff1a; ​ //每次访问该链接会生成随机头像 https://joeschmoe.io/api/v1/random​​//末尾的123可以改成其他数字&#xff0c;不同的数字能产生不同的头像&#xff0c; https://joeschmoe.io/api/v1…

四级,六级报名网站很卡怎么办?

报名四级&#xff0c;六级的同学总是遇到网站很卡的问题&#xff0c;要么加载不出来&#xff0c;就算等了好久加载出来了&#xff0c;稍微一操作&#xff0c;又变成白屏了。马上google一下&#xff0c;大多说505 HTTP Version Not Supported是由于服务器对http1.1协议不支持或者…

javaweb报错Connections could not be acquired from the underlying database,测试类可以通过,但是网站显示无法连接数据库

无法连接数据可的原因有很多&#xff1a; 1.检查jdbc.driver&#xff0c;jdbc.url&#xff0c;jdbc.username&#xff0c;jdbc.password是否配置错误 #若使用的mybatis版本是8.0以上的&#xff0c;则驱动器要加上cj jdbc.drivercom.mysql.cj.jdbc.Driver #如果使用的是MySQL8…

Web --- 电影网站

题目 代码 <!DOCTYPE html> <html><head><meta charset"utf-8"><title>作业三</title><style>td{width: 80px;}img{width: 214.5px;height: 303.75px;}</style></head><body><div><div class…

大型网站架构之分布式消息队列

以下是消息队列以下的大纲&#xff0c;本文主要介绍消息队列概述&#xff0c;消息队列应用场景和消息中间件示例&#xff08;电商&#xff0c;日志系统&#xff09;。 本次分享大纲 消息队列概述消息队列应用场景消息中间件示例JMS消息服务常用消息队列参考&#xff08;推荐&…

个人网站搭建之快速入门

1. 写在前面 本文只是指导新手快速搭建一个简单的用于学习和自己玩的网站&#xff0c;预计完成时间1-2天&#xff0c;未考虑高并发、高可用、持续集成和运维运营等问题&#xff0c;适合于新手入门和学习&#xff0c;无需任何基础&#xff08;后面部署可能会需要一丢丢专业知识…

【开源探索】各种高仿网站合集

返回 CSDN目录 查看 github项目 1. 功能简述 仓库收集了近70热门网站的克隆高仿源码。包括Airbnb、亚马逊、抖音、Netflix、Youtube、Discord等。 当你看到抖音等的时候是不是想快速做个山寨的&#xff1f;又不想耗时耗力&#xff0c;这个项目是你绝佳的选择 2. 开源地址 …

Linux搭建web网站综合实验

网站需求&#xff1a; 1.基于域名[www.openlab.com](http://www.openlab.com)可以访问网站内容为 welcome to openlab!!! 2.给该公司创建三个子界面分别显示学生信息&#xff0c;教学资料和缴费网站&#xff0c;基于[www.openlab.com/student](http://www.openlab.com/studen…

渗透测试中如何辨别网站使用的脚本语言

判断网站使用的脚本语言也是信息收集的一部分&#xff0c;通过判断使用的何种脚本语言&#xff0c;来扩大攻击面。 asp asp本身并不是一种脚本语言&#xff0c;他只是提供了一种使镶嵌在HTML页面中的脚本程序得以运行的环境&#xff0c;ASP采用脚本语言VBScript(Java script)作…

微信扫码第三方登录,网站授权,redirect_url参数错误

最近在实现一个用微信扫码授权登录的项目&#xff0c;不是测试号&#xff0c;而是所有人都能登录&#xff0c;这就涉及到去微信开发平台申请应用了&#xff0c;具体的呢很多地方都有。 就是为了申请appid和AppSecret来进行实现&#xff0c; 废话不多说&#xff0c;很多人都遇…

小而美的博客网站-导入本地教程

前言&#xff1a; 在前人的基础上增加一些技术支持&#xff0c;便于在本地服务器使用&#xff0c;如需实现部署与上线&#xff0c;请百度。 第一步 下载 下载源码到本地&#xff0c;这个可以百度或者私聊我 第二步 导入 导入IDEA工具 之后可能需要配置maven&#xff0c;j…

常见的网站架构类型

0x01 简介 常见的服务器操作系统&#xff1a; Window --- Windows ServerLinux --- Cent OSUNIX --- HP-UX和IBM AIX&#xff0c;主要应用于金融证券等行业用户 在平台下架设Web服务器软件&#xff1a;Windows附带的IIS、Apache、Nginx 0x02 几款服务器 IIS&#xff1a;In…