0%

爬虫初试

爬虫基础

一、君子协议

image-20220106150517345

服务器渲染:在服务器那边直接把数据和HTML整合在一起,统一返回给浏览器

客户端渲染:第一次请求只拿到和HTML的骨架,第二次请求拿到数据,进行结合,在页面源代码中,看不到数据,拿到数据需要进行抓包

二、数据解析

  1. re解析 正则表达式 快
  2. bs4解析 简单 效率低
  3. xpath解析 流行的解析方式

正则表达式

语法:使用元字符进行排列

image-20220108104224319

image-20220108110035577

eg:爬取电影天堂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# -*- coding:utf-8 -*-
# @Time :2022/4/22 10:28
# @SOFTWARE :爬虫学习

import re
import requests
import csv

domain = "https://www.dytt89.com/"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44"
}
resp = requests.get(domain,headers = headers,verify = False) # 若出现安全验证,直接添加 Verify = False 跳过即可
resp.encoding = "gb2312"
result1 = resp.text
resp.close()
# print(resp.text)
obj1 = re.compile(r"2022新片精品(?P<ul>.*?)</ul>",re.S)
obj2 = re.compile(r"<li><a href='(?P<href>.*?)' title=",re.S)
obj3 = re.compile(r'片  名(?P<movie>.*?)<br />.*?<tr>.*?<a href="(?P<dlocation>.*?)">',re.S)
result2 = obj1.finditer(result1)
f = open("data2.csv",mode = "w")
csvwriter =csv.writer(f)
child_href_list = []
for it in result2:
ul = it.group("ul")
result3 = obj2.finditer(ul)
for itt in result3:
child_href = domain + itt.group("href").strip("/")
child_href_list.append(child_href)
# print(child_href)
# print(itt.group("href"))
# print(itt.group("movie"))
for href_ in child_href_list:
resp2 = requests.get(href_,headers = headers,verify = False)
resp2.encoding = "gb2312"
child_page = resp2.text
resp2.close()
resutl4 = obj3.search(child_page)
# print(resutl4.group("movie"))
# print(resutl4.group("dlocation"))
dic = resutl4.groupdict()
csvwriter.writerow(dic.values())
f.close()
print("over!")



bs4

思路:以爬取优美图库为例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# -*- coding:utf-8 -*-
# @Time :2022/1/8 18:16
# @SOFTWARE :爬虫学习


import requests
from bs4 import BeautifulSoup
import time

#解析数据
#1. 把页面源代码交给BeautifulSoup进行处理,生成bs对象
#2.从bs对象中查找数据
## find(标签,属性 = 值) 一个
## find_all(标签,属性 = 值) 一堆
# class_="" 加下划线课可避免与关键字重复
#或者 attrs = { "class":""}

#1.拿到主页面的源代码,然后提取到子页面的链接地址,href
#2.通过href拿到子页面的内容,从子页面中找到图片的下载地址 img->src
#3.下载图片

url = "https://www.umei.cc/bizhitupian/weimeibizhi/"
resp = requests.get(url)
resp.encoding = "utf-8" #解码

# 把源代码交给bs

main_page = BeautifulSoup(resp.text,"html.parser")
alist = main_page.find("div",class_="TypeList").find_all("a") #把范围第一次缩小
for a in alist:
href_first = (a.get("href"))
href = "https://www.umei.cc" + href_first
#拿到子页面源代码
child_page_resp = requests.get(href)
child_page_resp.encoding = "utf-8"
child_page_text=child_page_resp.text
child_page = BeautifulSoup(child_page_text,"html.parser")
p = child_page.find('p',align = "center")
img = p.find("img")
src = img.get("src")
img_resp = requests.get(src)
img_name = src.split("/")[-1]
with open("img/"+img_name,mode="wb") as f:
f.write(img_resp.content)

print("over!",img_name)
time.sleep(1)
print("all over!!!")




Xpath

在XML文档中搜索内容的一门语言

注意:不能匹配tbody标签 可以//越过tbody

html是xml的一个子集

image-20220809194038940

image-20220809203104892

eg:爬取猪八戒网

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# -*- coding:utf-8 -*-
# @Time :2022/1/10 9:41
# @SOFTWARE :爬虫学习
import requests
from lxml import etree

url = "https://taiyuan.zbj.com/search/f/?kw=SAAS"
resp = requests.get(url)
# resp.encoding = "utf-8"

html = etree.HTML(resp.text)

divs = html.xpath("/html/body/div[6]/div/div/div[2]/div[5]/div[1]/div")
for div in divs:
price = div.xpath("./div/div/a/div[2]/div[1]/span[1]/text()")
amount = div.xpath("./div/div/a/div[2]/div[1]/span[2]/text()")
name = div.xpath("./div/div/a/div[2]/div[2]/p/text()")
location =div.xpath("./div/div/a[1]/div[1]/div/span/text()")
print(location)

三、多线程

线程:执行单位

进程:资源单位,每一个进程至少有一个线程

启动一个程序,默认有一个主线程

多线程创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 第一种:简单,直白
from threading import Thread # 线程类
t = Thread(target = 函数, args = ("xxx",)) # 创建线程,并给线程交代任务,若函数需要传参,arg的值必须为 元组
t.start() # 开始执行该线程 -> 多线程状态为可以开始状态,具体执行由CPU决定
t2 = Thread(target = 对象(函数))
t2.start()

# 第二种:正规
class MyThread(Thread): # 继承类
def __init__:
# 对于传参 定义init类
def run(self): # 固定格式 -> 当线程被启动之后,被执行的就是run() 即下方的t.start()执行之后
for i in range(1000):
print("子线程",i)
if __name__ = "__main__":
t = MyThread()
t.start()


多进程创建

1
2
3
4
5
6
7
8
9
10
from multiprocessing import Process
def func():
for i in range(1000):
print("func",i)

if __name__ == '__main__':
p = Process(target=func)
p.start()
for i in range(1000):
print("main",i)

线程池:一次性开辟一些线程,用户直接给线程池提交任务,线程任务的调度交给线程池来完成

1
2
from concurrent.futures import ThreadPoolExecutor(线程池类),ProcessPoolExecutor(进程池类)

四、常用数据解析方法

image-20220809191021835

  1. re解析 正则表达式

思路:使用元字符进行匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.       匹配除换行符之外的任意字符
\w 匹配字母或数字或下划线
\s 匹配任意的空白符
\d 匹配数字
\n 匹配一个换行符
\t 匹配一个制表符

^ 匹配字符串的开始
$ 匹配字符串的结尾

\W 匹配非字母或数字或下划线
\D 匹配非数字
\S 匹配非空白符
a|b 匹配字符a或字符b
() 匹配括号内的表达式,也表示一个组
[...] 匹配字符组中的数字
[^...] 匹配除了字符组中字符的所有字符

量词: 控制前面的元字符出现的次数
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n.} 重复n次或更多次
{n,m} 重复n到m次

.* 贪婪匹配
.*? 惰性匹配

Eg: 爬取盗版电影天堂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# -*- coding:utf-8 -*-
# @Time :2022/4/22 10:28
# @SOFTWARE :爬虫学习

import re
import requests
import csv

domain = "https://www.dytt89.com/"
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/100.0.4896.127 Safari/537.36 Edg/100.0.1185.44"
}
resp = requests.get(domain,headers = headers,verify = False) # 若出现安全验证,直接添加 Verify = False 跳过即可
resp.encoding = "gb2312"
result1 = resp.text
resp.close()
# print(resp.text)
obj1 = re.compile(r"2022新片精品(?P<ul>.*?)</ul>",re.S)
obj2 = re.compile(r"<li><a href='(?P<href>.*?)' title=",re.S)
obj3 = re.compile(r'片  名(?P<movie>.*?)<br />.*?<tr>.*?<a href="(?P<dlocation>.*?)">',re.S)
result2 = obj1.finditer(result1)
f = open("data2.csv",mode = "w")
csvwriter =csv.writer(f)
child_href_list = []
for it in result2:
ul = it.group("ul")
result3 = obj2.finditer(ul)
for itt in result3:
child_href = domain + itt.group("href").strip("/")
child_href_list.append(child_href)
# print(child_href)
# print(itt.group("href"))
# print(itt.group("movie"))
for href_ in child_href_list:
resp2 = requests.get(href_,headers = headers,verify = False)
resp2.encoding = "gb2312"
child_page = resp2.text
resp2.close()
resutl4 = obj3.search(child_page)
# print(resutl4.group("movie"))
# print(resutl4.group("dlocation"))
dic = resutl4.groupdict()
csvwriter.writerow(dic.values())
f.close()
print("over!")
  1. bs4

Eg: 爬取优美图库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# -*- coding:utf-8 -*-
# @Time :2022/1/8 18:16
# @SOFTWARE :爬虫学习


import requests
from bs4 import BeautifulSoup
import time

#解析数据
#1. 把页面源代码交给BeautifulSoup进行处理,生成bs对象
#2.从bs对象中查找数据
## find(标签,属性 = 值) 一个
## find_all(标签,属性 = 值) 一堆
# class_="" 加下划线课可避免与关键字重复
#或者 attrs = { "class":""}

#1.拿到主页面的源代码,然后提取到子页面的链接地址,href
#2.通过href拿到子页面的内容,从子页面中找到图片的下载地址 img->src
#3.下载图片

url = "https://www.umei.cc/bizhitupian/weimeibizhi/"
resp = requests.get(url)
resp.encoding = "utf-8" #解码

# 把源代码交给bs

main_page = BeautifulSoup(resp.text,"html.parser")
alist = main_page.find("div",class_="TypeList").find_all("a") #把范围第一次缩小
for a in alist:
href_first = (a.get("href"))
href = "https://www.umei.cc" + href_first
#拿到子页面源代码
child_page_resp = requests.get(href)
child_page_resp.encoding = "utf-8"
child_page_text=child_page_resp.text
child_page = BeautifulSoup(child_page_text,"html.parser")
p = child_page.find('p',align = "center")
img = p.find("img")
src = img.get("src")
img_resp = requests.get(src)
img_name = src.split("/")[-1]
with open("img/"+img_name,mode="wb") as f:
f.write(img_resp.content)

print("over!",img_name)
time.sleep(1)
print("all over!!!")
  1. xpath

Eg: 爬取猪八戒网

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# -*- coding:utf-8 -*-
# @Time :2022/1/10 9:41
# @SOFTWARE :爬虫学习
import requests
from lxml import etree

url = "https://taiyuan.zbj.com/search/f/?kw=SAAS"
resp = requests.get(url)
# resp.encoding = "utf-8"

html = etree.HTML(resp.text)

divs = html.xpath("/html/body/div[6]/div/div/div[2]/div[5]/div[1]/div")
for div in divs:
price = div.xpath("./div/div/a/div[2]/div[1]/span[1]/text()")
amount = div.xpath("./div/div/a/div[2]/div[1]/span[2]/text()")
name = div.xpath("./div/div/a/div[2]/div[2]/p/text()")
location =div.xpath("./div/div/a[1]/div[1]/div/span/text()")
print(location)
  • ```python

    -- coding:utf-8 --

    @Time :2022/8/9 18:57

    @SOFTWARE :爬虫学习

    “””

    响应内容的分类:
        1.结构化:
            json数据(高频出现): json模块  re模块    jsonpath模块
            xml数据(低频出现):  re模块    lxml模块  bs4模块
        2.非结构化:
            html数据:re模块  lxml模块
    
    xml:
        可拓展标记语言 更专注于对数据的传输和存储
    

    “””

    jsonpath 多层嵌套的复杂字典直接提取数据

    import jsonpath

    $ 根节点 最外层的大括号

    . 子节点

    .. 内部任意位置 子孙结点

    jsonpath 结果为列表 获取数据需要索引

    lxml模块 使用

    import lxml

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236

    -

    ## 五、scrapy爬虫框架

    - ### CrawlSpider:类 Spider的一个子类

    - 全站数据爬取的方式:

    - 基于Spider:手动请求
    - 基于CrawlSpider

    - CrawlSpider的使用:

    - 创建 一个工程
    - cd xxx
    - 创建爬虫文件(CrawlSpider):
    - scrapy genspider -t crawl xxx www.xxxx.com
    - LinkExtractor 链接提取器
    - 作用:根据指定规则((allow=r'正则'))进行指定链接的提取
    - 规则解析器
    - 作用:将链接提取器提取到的链接进行指定规则(callback) 的解析操作
    - 需求:爬取网站的编号 标题 内容 标号
    - 分析:爬取的数据没有在同一张页面中
    - 1. 可以使用链接提取器提取所有的页码链接
    2. 让链接提取器提取所有的详情页的链接

    - ### 分布式爬虫

    - 概念:我们需要搭建一个分布式机群 让其对一组资源进行分布式联合爬取

    - 作用:提升爬虫效率

    - 如何实现分布式?

    - 安装scrapy-redis的组件

    - 原生的sctapy是不可以试下分布式爬虫 必须要让scrapy结合着scrapy-redis组件一起实现分布式爬虫

    - 为什么原生的scrapy不能实现分布式?

    - 调度器不可以被分布式机群共享
    - 管道不可以被分布式机群共享

    - scrapy-redis组件的作用:

    - 可以给原生的scrapy框架提供可以被共享的管道和调度器

    - 实现流程

    - 创建一个工程

    - 创建一个基于CrawlSpider的爬虫文件

    - 修改当前的爬虫文件:

    - 导包 from scrapy_redis.spider import RedisCrawlSpider
    - 将start_url 和 allowed_domains 进行注释

    - 修改配置文件settings

    - 指定使用可以被共享的管道

    - ITEM_PIPELINES = { 'scrapy_redis.pipelines.RedisPipeline' : 400}

    - 指定调度器

    - 增加一个去重容器类的配置 作用使用Redis的set集合来存储请求的指纹数据

    DUPEFILTER_CLASS = "scrapy_redis.dupefilter.REFDupeFilter"

    - 使用scrapy_redis组件自己的调度器

    SCHEDULER = "scrapy_reds.scheduler.Scheduler"

    - 配置调度器是否要持久化 也就是当爬虫结束了 要不要清空Redis中请求队列和去重指纹的set 实现增量式爬虫 只爬取没有爬过的网站

    SCHEDULER_PERSIST = True

    - redis相关操作配置:

    - 配置redis的配置文件:

    - ### 增量式爬虫

    - 概念:检测网站数据更新的情况 只会爬取网站最新更新出来的数据
    - 分析
    - 指定一个起始rul
    - 基于CrawlSpider获取其他页码链接
    - 基于rule将其他页码链接进行请求
    - 从每一个页码对应的源码中解析出每一个电影详情页的url
    - 核心: 检测电影详情页的url之前有没有请求过
    - 将爬取过的电影详情页的url存储
    - 存储到Redis的set数据结构(自动去重)中
    - 对详情页url发起请求 然后解析出电影的名称和简介
    - 进行持久化存储



    ## 六、js算法解析处理



    - ### 常见的加密算法

    - 线性散列MD5算法
    - 对称加密DES/AES算法
    - 非对称加密算法RSA
    - base64伪加密
    - https证书秘钥加密





    ### MD5加密

    MD5是一种被广泛使用的线性散列算法 可以产出一个128位 (16字节) 的散列值(hash value) 用于确保信息传输的一致性 且MD5加密之后产生的是一个固定长度(32位或者16位)的数据

    - #### 解密

    - 理论上不存在解密 但可以进行反向暴力破解

    - #### 增加破解的成本

    - 使用一段无意义且随机生成的私钥进行MD5加密会生成一个加密串1
    - 将要加密的数据跟串1进行拼接 再进行一次MD5加密 生成串2
    - 将串2再进行MD5加密 生成的串3就是最终加密后的数据

    - 注册账号时的密码 一般使用MD5加密





    ### DES/AES算法加密

    - DES:Data Encraption Standard 即数据加密标准 是一种使用秘钥加密的算法 该加密算法是一种**对称加密方式** 其加密运算 解密运算需要使用的是同样的秘钥(一组字符串)
    - 注意
    - 现在用这个AES标准代替DES
    - AES和DES的区别
    - DES加密后密文长度是8的整数倍
    - AES加密后密文长度是16的整数倍
    - 应用场景的不同
    - 企业级开发使用DES足够安全
    - 如果要求高使用AES
    - DES/AES切换只需要修改CraptoJS.AES <=> CraptoJS.DES
    - 使用AES/DES进行数据交互时要求双方都拥有相同的私钥
    - 破解方法
    - 暴力破解
    - DES如果使用56位的秘钥 则可能的秘钥数量是2的56次方个
    - DES算法的四个入口参数:
    - Key 、Data 、Mode、 padding



    ### RSA加密

    ​ RSA加密算法是一种**非对称加密算法** 在公开秘钥加密和电子商业中RSA被广泛使用

    - 非对称加密算法

    - 非对称加密算法需要有两个秘钥:
    - 公开秘钥 简称公钥 publickey
    - 私有秘钥 简称私钥 privatekey
    - 公钥与私钥是一对 如果公钥对数据加密 只有对应的私钥才能解密 。因为加密和解密使用的是两个不同的秘钥 所以叫做非对称加密

    - 注意

    - 使用时都是使用公钥加密 私钥解密 公钥可以公开 私钥自己保留
    - 算法强度复杂、安全性依赖于算法与秘钥但是由于其算法复杂 而使得加密解密速度没有对称加密解密的快

    - 使用流程和场景介绍

    - 通过公钥加密 使用私钥解密 **私钥是通过公钥计算生成的** 假设ABC三方之间相互进行加密通信。大家相互之间使用公钥进行信息加密 信息读取时使用各自对应的私钥进行信息解密
    - 用户输入的支付密码会通过RSA加密



    ### Base64伪加密

    - Base64是一种用64个字符来表示任意二进制数据的方法。base64是一种编码方式而不是加密算法。只是看上去像是加密而已。
    - Base64使用A-Z a-z 0-9 + / 这64个字符实现对数据进行加密



    HTTPS加密

    ​ https是基于http和SSL/TLS实现的一个协议 他可以保证在网络上传输的数据都是加密的 从而保证数据安全

    - http协议是不安全的

    - http协议在数据传输的过程中都是铭文 所以存在在数据泄露和篡改

    - 使用对称秘钥进行数据加密

    - 为了防止数据泄露和篡改 我们队数据进行加密 可以生成一个对称密码 将对称秘钥分别交给浏览器和服务器端 他们之间传输的数据都使用对称秘钥进行加密和解密

    - 请求和响应流程:

    - 客户端使用对称秘钥对请求进行加密并发送给服务端
    - 服务端接收到密文后 使用对称秘钥进行解密 然后处理请求 最后使用对称秘钥把返回数据进行加密 返回给客户端
    - 客户端接收到密文后 使用对称秘钥进行解密 得到响应内容





    ## 三、selenium

    自动化测试工具

    环境搭建:

    1. pip install selenium
    2. 安装浏览器驱动webdriver

    - ```python
    # -*- coding:utf-8 -*-
    # @Time :2022/8/10 10:34
    # @SOFTWARE :爬虫学习

    from selenium import webdriver

    url = "http://www.baidu.com"

    driver = webdriver.ChromiumEdge

    driver.get(url)

    print(driver.page_source)

    print(driver.current_url)

    print(driver.title)

  • 抓取某拉钩视频

    • ```python

      -- coding:utf-8 --

      @Time :2022/5/2 10:32

      @SOFTWARE :爬虫学习

      from selenium import webdriver
      import time
      from selenium.webdriver.common.keys import Keys
      from selenium.webdriver.common.by import By
      from selenium.webdriver.edge.options import Options # 无头浏览器web = webdriver.Edge()web.get(“https://www.lagou.com/")
      el = web.find_element(By.XPATH,’//*[@id=”changeCityBox”]/p[1]/a’)

      el = web.find_element_by_xpath(‘//*[@id=”changeCityBox”]/p[1]/a’)

      el.click()

      time.sleep(2)

      web.find_element_by_xpath(‘//*[@id=”search_input”]’).send_keys(‘python’, Keys.ENTER)

      web.find_element(By.XPATH,’//[@id=”search_input”]’).send_keys(‘python’,Keys.ENTER)
      li_list = web.find_elements(By.XPATH,’//
      [@id=”jobList”]/div[1]/div’)
      for li in li_list:
      company_name = li.find_element(By.XPATH,'./div[1]/div[2]/div[1]/a').text # //*[@id="jobList"]/div[1]/div[1]/div[1]/div[2]/div[1]/a
      price = li.find_element(By.XPATH,'./div[1]/div[1]/div[2]/span').text
      location = li.find_element(By.XPATH,'./div[1]/div[1]/div[1]/a').text
      # job = li.find_element(By.XPATH,'')
      print(price,company_name,location)
      

      如何进行切换窗口

      当我们利用selenium打开新窗口时,默认还在原来的窗口

      web.switch_to.window(web.window_handles[-1])

      web.close()

      处理iframe,需要先切拿到iframe,切换到iframe,再进行拿数据

      web.switch_to.frame(xxx) 切换到iframe 页面

      web.switch_to.default_content() 切换回原页面

      无头浏览器 -> 让浏览器后台运行,界面不出现

      from selenium.webdriver.edge.options import Options # 无头浏览器

      opt = Options()

      opt.add_argument(“–headless”)

      opt.add_argument(“–disbale–gpu”)

      web = webdriver.Edge(options=opt)

      class car():
      def __init__(self):
          pass
      def __str__(self):
          return 1
      def __del__(self):
          pass
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64

      -


      ## 四、相关库

      - session

      - ```python
      # -*- coding:utf-8 -*-
      # @Time :2022/8/9 11:56
      # @SOFTWARE :爬虫学习

      import requests
      import re
      """
      requests.session 进行状态保持
      作用:
      自动处理cookie
      场景:
      连续的多次请求

      """
      def login():
      # session对象
      session = requests.session()

      # headers
      session.headers = {
      "user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.81 Safari/537.36 Edg/104.0.1293.47"
      }

      # url1 获取token
      url1 = "https://github.com/login"
      # 发送请求获取相应
      res1 = session.get(url1).content.decode()
      # 正则提取
      token = re.findall('name="authenticity_token" value="(.*?)" />',res1)[0]
      # print(token)


      # url2 登录
      url2 = "https://github.com/session"
      # 构建表单数据
      data = {
      "commit": "Sign in",
      "authenticity_token": token,
      "login": "1946497315@qq.com",
      "password": "Yzh963987",
      "webauthn-support": "supported",
      "webauthn-iuvpaa-support": "supported",
      }
      # 发送请求登录
      res2 = session.post(url2,data = data)

      # url3 验证
      url3 = "https://github.com/Bajibajj"
      response = session.get(url3)
      with open('github.html','wb') as f:
      f.write(response.content)


      if __name__ == '__main__':
      login()
  • post提交表单

    • ```python

      -- coding:utf-8 --

      @Time :2022/8/9 11:21

      @SOFTWARE :爬虫学习

      import requests
      import json

      url

      headers

      data

      1.固定值 抓包获取的不变值

      2.输入值 抓包比较

      3.预设值 静态文件 需要提前从惊天html中获取

      4.预设值 发送请求 需要对指定地址发送请求

      5.在客户端生成 分析js模拟生成数据

      发送请求相应

      数据解析 json

      url

      url = “https://fanyi.baidu.com/v2transapi?from=zh&to=en"

      headers

      headers = {
      “User-Agent”: “Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.81 Safari/537.36 Edg/104.0.1293.47”
      }dat = {
      "from": "zh",
      "to": "en",
      "query": "字典",
      "transtype": "realtime",
      "simple_means_flag": "3",
      "sign": "763934.1002287",
      "token": "198e3bfc271aca63eb0ea4a09e56f78b",
      "domain": "common"
      
      }res = requests.post(url,headers = headers,data=dat)print(res.content.decode())
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16

      - verify

      - ```python
      # -*- coding:utf-8 -*-
      # @Time :2022/8/9 11:16
      # @SOFTWARE :爬虫学习

      import requests

      url = "http://www.baidu.com"


      response = requests.get(url,verify = False)

      print(response.text)