【爬虫】爬虫5-反爬问题和Xpath

爬虫5-反爬问题和Xpath

1. 登录问题

1.1 resquests 的登录问题

  • requests自动登录步骤
    • 第一步:人工对自动登录的网页进行登录
    • 第二步:获取网站登陆后的cookie信息
    • 第三步:发送请求到时候在请求头中添加cookie值
import requests
header = {
    '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',
    'cookie': 'cookie: _zap=ed17347f-a0b9-4fcc-9151-fa5f6a4caa36; d_c0="AJBfjK4zHBSPTpqD6euH_nN1u_SyonmdU4E=|1638269979"; _9755xjdesxxd_=32; YD00517437729195%3AWM_TID=vszHQtFpvr1EAQQUVVY%2B49fAEhGTlXCN; _xsrf=0649db01-f4db-4e0e-86d7-8d3c16844cc4; Hm_lvt_98beee57fd2ef70ccdd5ca52b9740c49=1679122159,1679454090,1680101058,1680318443; captcha_session_v2=2|1:0|10:1680318443|18:captcha_session_v2|88:bXBja0tQZ2pEVGV2bEdadXprOVFwOXg1eFM3WlA1alU2TDRtZjRyU1pVUUtJUWF3aWdyd1ZsQ3NGdW9JYXVqaQ==|471b86e3de25ca7d15c79cc23104feab297bf074f39ae8f8f7a1010b4c5dad2f; SESSIONID=VK2SVoKCNEWpPBLM8U2DDCfdJgZVvZOK1TUmyClvzUW; osd=UlwRC04nEkdDbxajLC5zHi2-CYQ8dVl5HTx96GNsUxA_MlHrYc-BYS9uEq8t_NBW6IjHOXJH2goFfOwZPtJ9VuY=; JOID=U18QCk8mEUZCbhegLS9yHy6_CIU9dlh4HD1-6WJtUhM-M1DqYs6AYC5tE64s_dNX6YnGOnNG2wsGfe0YP9F8V-c=; __snaker__id=bS1DlrKkmaNCoSwh; gdxidpyhxdE=UNnThIiUp%2FnSxdTzG0EVvGUCARfS%5Ckn45Y4NhM5v4e1yCzvkqze9AE8jeB6%5CffQ4PcADCdu9WqAZof80OhwM1hdgRCG%2F9IN40Mq3voC3o6OLjMZybLrJWIJlIOmRcP7pWmdYzbCkXWH57QC4yjTV9Q11ZjvIc1Ws1SQIy294Kv1sDgc3%3A1680319344655; YD00517437729195%3AWM_NI=s3RPSAJf1Ix%2F3ap4IbQ8q17uTSnAEhUHb9qYp47EWn9yB0X3jpC3tmRXC9Hv2rc2bXDJVfaT6DyIQKnK9jv03Xm7bZFpObK%2FFtpfjZ6GtO6pc2QzCAFXaPNSB%2FsgC5p%2FVk4%3D; YD00517437729195%3AWM_NIKE=9ca17ae2e6ffcda170e2e6eea3d46aa1b88790dc649cac8ea6c84a939a9bacc848bcaa82d9e260a286baa7d42af0fea7c3b92ab1ed9eb1d24b8abaffaafb25f1bfc0d5cc6a93e8bfd2b67f988da2a2c8649798aedaf453b4ecf9a6d666fba78ed1db39aab08dd4f76792888ddacb7ef2aeadd3e15488969a87e460f69cb7aad441ae95f78bf53cf188a3d8e15286b08183ca2586acc087e952f699bcb0b57ca1ee9f9bc24b8688afb1cd5982f1bd88c23fb4f19a8cb737e2a3; q_c1=411a6a4dded943fbb14e4a1c7ac13427|1680318717000|1680318717000; Hm_lpvt_98beee57fd2ef70ccdd5ca52b9740c49=1680318720; z_c0=2|1:0|10:1680318720|4:z_c0|92:Mi4xTTRLQUVBQUFBQUFBa0YtTXJqTWNGQ1lBQUFCZ0FsVk5fZTRVWlFCeHdTc2toMTdfeHE5UUhmTWFIaVpPSTlqRlVn|d4150da1285e8366e4a9cf1b87ce46365ee9756187a1371ab5f186cd5a73a5a6; tst=r; KLBRSID=ed2ad9934af8a1f80db52dcb08d13344|1680318832|1680318442'
}
response = requests.get('https://www.zhihu.com/', headers=header)

print(response.text)

1.2 selenium 的登录问题

1)selenium获取cookie

from selenium.webdriver import Chrome

# 1.创建浏览器打开需要自动登录的网站
b = Chrome()
b.get('https://www.taobao.com')

# 2.留足够长的时间,人工完成登录(必须得保证b指向的窗口的网页中能看到登陆成功以后的信息)
# 输入前记得切换回原网页,重新刷新
input('是否已经完成登录:')

# 3.获取登录成功后的cookie信息,保存到本地文件
result = b.get_cookies()
with open('files/taobao.txt', 'w', encoding='utf-8') as f:
    f.write(str(result))

2)selenium使用cookie

  • 创建浏览器打开需要自动登录的网站
  • 获取本地保存的cookie
  • 添加cookie
  • 重新打开网页
from selenium.webdriver import Chrome
# 1.创建浏览器打开需要自动登录的网站
b = Chrome()
b.get('https://www.taobao.com')

# 2.获取本地保存的cookie
with open('files/taobao.txt', encoding='utf-8') as f:
    result = eval(f.read())

# 3. 添加cookie
for x in result:
    b.add_cookie(x)

# 4. 重新打开网页
b.get('https://www.taobao.com')

input('end:')

2. 代理

当IP被封,网站无法打开时,可以通过获取代理的方法爬取数据

请添加图片描述

1)购买代理

例如极光代理

将当前IP(可以直接通过百度IP地址查询当前IP)加入白名单中

请添加图片描述

将获得的网址加载得到代理IP

2.1 代理IP

  • 添加proxies = { ‘https’: ‘代理IP’}
import requests

headers = {
    'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.0.0 Safari/537.36'
}
proxies = {
    'https': '114.106.171.182:4554'
}
res = requests.get('https://movie.douban.com/top250?start=0&filter=', headers=headers,proxies=proxies)
print(res.text)

2.2 selenium的代理

  • 添加options.add_argument(‘–proxy-server=http://代理IP’)
from selenium.webdriver import Chrome, ChromeOptions

options = ChromeOptions()
# 设置代理
options.add_argument('--proxy-server=http://114.106.171.182:4554')

b = Chrome(options=options)
b.get('https://movie.douban.com/top250?start=0&filter=')

input()

3. Xpath

  • Xpath用来解析网页数据或者xml数据的一种解析方法,它是通过路径来获取标签

3.1 常见的几个概念

1)树:整个网页结构或者xml就是一个树结构
2)元素(节点):html树结构中的每个标签
3)根节点:树结构中的第一个节点
4)内容:标签内容
5)属性:标签属性

3.2 Xpath语法

1)路径

  • 绝对路径:以’/'开头,然后从根节点层层往下写路径

  • 相对路径:写路径的时候用’.‘或者’…‘开头,期中’.‘表示当前节点,’…'表示当前节点父节点

    注意:如果路径是以’./'开头,可省略

  • 全路径:以’//'开头的路径

2)获取标签内容:在获取标签路径的最后加’/text()

3)获取标签属性:在获取标签路径的最后加’/@属性名

4)加谓语(加条件) - 路径中的节点[]

  • 位置相关谓语
    • [N] - 第N个指定标签
    • [last()] - 最后一个指定标签
    • [last()-N]
    • [position()>N]、[position()>=N]、[position()<N]、[position()<=N]
  • 属性相关谓语
    • [@属性名=属性值]

5)通配符

  • xpath中可以通过来表示任意标签或者任意属性*

3.3 应用

from lxml import etree

# 1.创建树结构,获取节点
html = open('data.html', encoding='utf-8').read()
root = etree.HTML(html)

# 2. 通过路径获取标签
# 节点对象.xpath(路径)    -   根据获取所有标签,返回值是列表,列表中的元素是节点对象

# ------------------------------绝对路径-----------------------------
# 1)绝对路径
result = root.xpath('/html/body/div/a')
print(result)

# 获取标签内容
result = root.xpath('/html/body/div/a/text()')
print(result)   # ['我是超链接2', '我是超链接4']

# 获取标签属性
result = root.xpath('/html/body/div/a/@href')
print(result)   # ['https://www.baidu.com', 'https://www.taobao.com']

# 注意:就绝对路径写法跟xpath前面用谁去点无关
div = root.xpath('/html/body/div')[0]

result = div.xpath('/html/body/div/a/text()')
print(result)   # ['我是超链接2', '我是超链接4']

# ------------------------------相对路径-----------------------------

# 2)相对路径
result = root.xpath('./body/div/a/text()')
print(result)   # ['我是超链接2', '我是超链接4']

result = div.xpath('./a/text()')
print(result)   # ['我是超链接2', '我是超链接4']

result = div.xpath('a/text()')
print(result)   # ['我是超链接2', '我是超链接4']

# 注意:相对路径写法跟xpath前面用谁去点有关

# ------------------------------全路径-----------------------------

# 3)全路径
result = root.xpath('//a/text()')
print(result)   # ['我是超连接1', '我是超链接2', '我是超链接4', '我超链接3']

result = div.xpath('//a/text()')
print(result)   # ['我是超连接1', '我是超链接2', '我是超链接4', '我超链接3']

result = root.xpath('//div/a/text()')
print(result)   # ['我是超链接2', '我是超链接4', '我超链接3']
# div和a只能是父子关系

# 注意:全路径写法跟xpath前面用谁去点无关

# ------------------------------位置相关谓语-----------------------------

# 第二个
result = root.xpath('//span/p[2]/text()')
print(result)   # ['我是段落22']

# 最后一个
result = root.xpath('//span/p[last()]/text()')
print(result)   # ['我是段落55']

# 倒数第三个
result = root.xpath('//span/p[last()-2]/text()')
print(result)   # ['我是段落33']

#
result = root.xpath('//span/p[position()>=4]/text()')
print(result)   # ['我是段落44', '我是段落55']

# ------------------------------属性相关谓语-----------------------------

# span下p标签中class属性是c2的p标签
result = root.xpath('//span/p[@class="c2"]/text()')
print(result)   # ['我是段落22', '我是段落44']

result = root.xpath('//span/span[@title="hello"]/text()')
print(result)   # ['我是span11']

# ------------------------------通配符-----------------------------

# span下所有标签
result = root.xpath('//span/*/text()')
print(result)

# span下p标签属性是c1的p标签
result = root.xpath('//span/p[@class="c1"]/text()')
print(result)   # ['我是段落11', '我是段落33', '我是段落55']

# span下class属性是c1的标签
result = root.xpath('//span/*[@class="c1"]/text()')
print(result)   # ['我是段落11', '我是段落33', '我是段落55', '我是超链接11']

# span下span的任意属性
result = root.xpath('//span/span/@*')
print(result)   # ['hello', 'world']

# class属性是c1的所有标签
result = root.xpath('//*[@class="c1"]/text()')
print(result)   # ['我是段落11', '我是段落33', '我是段落55', '我是超链接11']

data.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <span>
        <span title="hello">我是span11</span>
        <span typeof="world">我是span22</span>
        <p class="c1">我是段落11</p>
        <p class="c2">我是段落22</p>
        <p class="c1" id="p1">我是段落33</p>
        <p class="c2">我是段落44</p>
        <p class="c1">我是段落55</p>

        <a class="c1">我是超链接11</a>
        <a class="c2">我是超链接22</a>
        <a class="c2">我是超链接33</a>
    </span>
<div>
    <p>
        <span>我是span1</span>
        <a href="">我是超连接1</a>
    </p>
    <a href="https://www.baidu.com">我是超链接2</a>
    <p>我是段落2</p>
    <a href="https://www.taobao.com">我是超链接4</a>
    <div>
        <div>
            <a href="">我超链接3</a>
        </div>
        <div>
            <p>我是段落3</p>
        </div>
    </div>
</div>
</body>
</html>

补充

xml、json属于通用语言,用来实现服务端和客户端不同于语言的转换

请添加图片描述

例如:python转换成json、xml

Python数据:{'name': 'xiaoming', 'age': 18, 'is_ad': True, 'car_no': None}

Json数据:{"name": "xiaoming", "age": 18, "is_ad": true, "car_no": null}

xml数据: 
<student class="优秀学员">
    <name>xiaoming</name>
    <age>18</age>
    <is_ad>是</is_ad>
    <car_no></car_no>
</student>

…(img-hOTgKqTi-1680430749480)]

例如:python转换成json、xml

Python数据:{'name': 'xiaoming', 'age': 18, 'is_ad': True, 'car_no': None}

Json数据:{"name": "xiaoming", "age": 18, "is_ad": true, "car_no": null}

xml数据: 
<student class="优秀学员">
    <name>xiaoming</name>
    <age>18</age>
    <is_ad>是</is_ad>
    <car_no></car_no>
</student>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值