栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python爬虫之利用xpath爬取ip代理网站的代理ip

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python爬虫之利用xpath爬取ip代理网站的代理ip

爬虫工具

python3 pycharm edge/chrome

requests库的用法

requests库是python中简单易用的HTTP库
用命令行安装第三方库 pip install requests
导入库import requests
获取响应内容

import requests
r = requests.get('http://www.baidu.com/')
print("文本编码:", r.encoding)  # ISO-8859-1
print("响应状态码:", r.status_code)
# print ("字符串方式的响应体:", r.text)
# 响应体乱码解决
print("字符串方式的响应体:", r.text.encode('ISO-8859-1'))
xpath的用法

xpath可以在XML文档中查找信息,在XML中通过元素和属性进行定位
常用的表达式

表达式描述
nodename选取此节点的所有子节点
/从根节点选取(取子节点)。
//从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置。
.选取当前节点
选取当前节点的父节点
@选取属性

谓语

路径表达式
//table/tbody/trtable标签下的tbody标签下的所有tr节点
//a/@src选取a标签下的src属性
//div[@class=“box”]选取的div节点
使用lxml解析

安装pip install lxml
导入库from lxml import etree
lxml将_html_文本转换为_xml_对象
实例化一个**etree**对象,且将解析的源码加载到该对象中

tree = etree.HTML(html)
# result = etree.tostring(tree) 补全html的基本写法
#                               比如补全缺少的结束标签   
xpath中的 text(), string(), data()的区别如下:
  • text()仅仅返回所指元素的文本内容
  • string()函数会得到所指元素的所有节点文本内容,这些文本会被拼接成一个字符串.
  • data()大多数时候和string()通用不建议经常使用.(可能会影响性能)
基本使用
from lxml import etree
wb_data = """
        
            
  • first item
  • second item
  • third item
  • fourth item
  • fifth item
""" html = etree.HTML(wb_data) print(html) result = etree.tostring(html) print(result.decode("utf-8"))

输出



        
用.text和/text()获取某个标签内容
# html = etree.HTML(wb_data)
# html_data = html.xpath('/html/body/div/ul/li/a')
# for i in html_data:
#    print(i.text)
    
html_data = html.xpath('/html/body/div/ul/li/a/@href')
# 或者 html_data = html.xpath('//li/a//@href')
for i in html_data:
    print(i)
爬取ip网站 简单爬取ip 对ip代理网站ip3366.net发起网络请求
import requests  # 不要忘记导入库
from lxml import etree

url = 'http://www.ip3366.net/'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36'
}  # headers是解决requests请求反爬的方法之一,伪装成浏览器
response = requests.get(url, headers=headers)
print(response.text)

发现是乱码,我们可以用print(response.encoding)打印出这个网站的编码是ISO-8859-1,所以我们用encode('_编码方式_')将我们爬取到的HTML改成这个编码

page_text = response.text.encode('ISO-8859-1')

创建etree实例对象用于解析HTML源码,并找到定位ip节点的位置

page_text = response.text.encode('ISO-8859-1')
tree = etree.HTML(page_text)
tr_list = tree.xpath('//*[@id="list"]/table/tbody/tr')  # tr的XML的列表
print(tr_list)
ip_list = []
for tr in tr_list:
    ip = tr.xpath('./td')[0].text + ':' + tr.xpath('./td')[1].text
	# 通过HTML源码看出ip和port的在td的第一个和第二个所以定位索引0,1的文本
	ip_list.append(ip)  #list.append(x) 将x加入list尾
print(ip_list)

输出:

[, , , , , , , , , ]
['113.252.11.250:8118', '103.143.196.50:8080', '115.218.4.39:9000', '27.159.188.239:3256', '115.218.0.13:9000', '118.114.110.231:8060', '103.82.170.211:808', '27.159.188.243:3256', '115.218.1.249:9000', '106.14.244.92:8080']

完整代码

# -*- coding = utf-8 -*-  默认utf-8的编码

import requests
from lxml import etree
url = 'http://www.ip3366.net/'
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36'
}  # headers是解决requests请求反爬的方法之一,伪装成浏览器
response = requests.get(url, headers=headers)
page_text = response.text.encode('ISO-8859-1')
tree = etree.HTML(page_text)
tr_list = tree.xpath('//*[@id="list"]/table/tbody/tr')  # tr的XML列表
print(tr_list)
ip_list = []
for tr in tr_list:
    ip = tr.xpath('./td')[0].text + ':' + tr.xpath('./td')[1].text
    ip_list.append(ip)
print(ip_list)
筛选ip

-我们向一个正常网站发起请求测试ip是否可用,不可用就在列表中删除
(我这个移除方法可能效率很低)

for i in ip_list:
    try:
        r = requests.get('http://2021.ip138.com/', headers=headers, proxies={"http": i}, timeout=2)
        if r.status_code == 200:
            pass
        else:
            ip_list.remove(i)
    except:
        ip_list.remove(i)

-我们从网站页面和HTML源码可以看出网站提供了每个代理ip的响应速度,我可以在存ip代理之前判断ip的响应速度再存。

        for tr in tr_list:
            tr_time = tr.xpath('./td')[6].text
            tr_time = tr_time.replace('秒', '')
            if float(tr_time) <= 2:
                ip = tr.xpath('./td')[0].text + ':' + tr.xpath('./td')[1].text
                ip_list.append(ip)
爬取多个页面

[http://www.ip3366.net/?stype=1&page=1](http://www.ip3366.net/?stype=1&page=1)第一页
[http://www.ip3366.net/?stype=1&page=2](http://www.ip3366.net/?stype=1&page=2)第二页
[http://www.ip3366.net/?stype=1&page=5](http://www.ip3366.net/?stype=1&page=5)第五页
通过观察每一页的网址我们可以发现传的page值就是页数的值
所以我们可以根据这个规律爬取多个网站

    for page in range(1, 5):
        url = 'http://www.ip3366.net/?page={}'.format(page)
        response = requests.get(url, headers=headers)
完整的代码:
import requests
from lxml import etree

def get_ip():
    ip_list = []
    tr_list = []
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36'
    }
    for page in range(1, 5):
        url = 'http://www.ip3366.net/?page={}'.format(page)
        response = requests.get(url, headers=headers)
        page_text = response.text.encode('ISO-8859-1')
        tree = etree.HTML(page_text)
        tr_list = tree.xpath('//*[@id="list"]/table/tbody/tr')



        for tr in tr_list:
            tr_time = tr.xpath('./td')[6].text
            tr_time = tr_time.replace('秒', '')
            if float(tr_time) <= 2:
                ip = tr.xpath('./td')[0].text + ':' + tr.xpath('./td')[1].text
                ip_list.append(ip)

    for i in ip_list:
        try:
            r = requests.get('http://2021.ip138.com/', headers=headers, proxies={"http": i}, timeout=2)
            if r.status_code == 200:
                pass
            else:
                ip_list.remove(i)
        except:
            ip_list.remove(i)
            
    print(ip_list)
    
if __name__ == '__main__':
    get_ip()
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/664208.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号