【学习笔记】 爬虫速成

网课知识点汇总

爬虫简介

什么是爬虫:通过编写程序,模拟浏览器上网,然后让其去互联网上抓取数据的过程。

风险:1、需要时常优化程序,避免干扰被访问网站的正常运行;2、在使用或传播爬取到的数据时,审查抓取到的内容,如果发现涉及到用户隐私、商业机密等敏感内容,需要及时停止

通用爬虫

抓取系统的重要组成部分。抓取的是一整张页面数据。

聚焦爬虫

建立在通用爬虫的基础之上。抓取的是页面中特定的局部内容。例:某条微博下的评论、豆瓣电影排行榜中评分高于9的电影

增量式爬虫

检测网站中数据更新的情况。只会抓取网站中更新出来的数据。

反爬机制

门户网站可以制定相应的策略或技术手段,防止爬虫程序进行网站数据的爬取

反反爬策略

爬虫程序可以通过制定相关的策略或者技术手段,破解门户网站中具备的反爬机制,从而获取数据

robots.txt协议

规定网站中哪些数据可以被爬取,哪些不可以被爬取,需要承担责任。

1
2
3
#打开方法
域名/robots.txt
#disallow不能爬取

http协议

概念:服务器和客户端进行数据交互的一种形式。

常用请求头信息

User-Agent:请求载体的身份标识

Connection:请求完毕后,是断开连接还是保持连接

常用响应头信息

Content-Type:服务器响应回客户端的数据类型

https协议

安全的超文本传输协议,涉及数据加密

加密方式

1、对称密钥加密:客户端将钥匙和锁一起发给服务器。如果请求被拦截会有安全隐患。

2、非对称密钥加密:使用的时候有两把锁,一把叫做私有密钥,一把是公开密钥,服务器首先告诉客户端按照自己给定的公开密钥进行加密处理,客户端按照公开密钥加密以后,服务器接收到信息再通过自己的私有密钥进行解密,好处是解密的钥匙不会进行传输,避免被挟持。缺点是效率低、公开密钥可能被篡改。

3、证书密钥加密:https采用的。服务器的开发者携带公开密钥,向数字证书认证机构提出公开密钥的申请,数字证书认证机构审核申请者的身份,审核通过以后,会对开发者申请的公开密钥做数字签名,分配这个已签名的公开密钥,并将密钥放在证书里面,绑定在一起。服务器将这份数字证书发送给客户端,因为客户端也认可证书机构,客户端可以通过数字证书中的数字签名来验证公钥的真伪,确保服务器传过来的公开密钥是真实的,一般情况下,证书的数字签名是很难被伪造的,这取决于认证机构的公信力。一旦确认信息无误之后,客户端就会通过公钥对报文进行加密发送,服务器接收到以后用自己的私钥进行解密。

requests模块

urllib模块:比较古早,爬虫繁琐,被替代了,课程中不介绍

requests模块:Python中原生的一款基于网络请求的模块,功能非常强大,简单便捷,效率极高。作用是模拟浏览器发请求

如何使用(requests模块的编码流程):指定url(网址)→发起请求(录入网址回车)→获取响应数据(显示网页)→持久化存储(存储数据)

环境安装:pip install requests(可用import requests检查,没反应说明已安装过)

例子1:爬取搜狗首页的页面数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#实战编码:爬取搜狗首页的页面数据
#新建源文件
import requests
#step-1:指定url,以字符串形式
url = 'https://www.sogou.com/'
#step-2:发起请求
#get方法会返回一个响应对象
response = requests.get(url = url)
#step-3:获取响应数据,text返回的是字符串形式的响应数据
page_text = response.text
print(page_text) #看是不是字符串类型的响应数据
#step-4:持久化存储
with open('./sogou.html','w',encoding = 'utf-8') as fp:
fp.write(page_text)
print('爬取数据结束')
#utf-8是指定编码,fp是随便起的名字,w代表写入,还有r读取,a追加,共三种基本模式
#会在本地生成一个sogou.html

例子2:爬取搜狗指定词条对应的搜索结果页面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#UA检测:门户网站的服务器会检测对应请求的载体身份标识,如果检测到请求的载体身份标识为某一款浏览器,说明该请求是正常请求。但如果检测到请求的载体身份标识不是基于某一款浏览器的,则表示该请求不正常(爬虫),服务器端可能拒绝该次请求。
#正常请求的User-Agent是身份标识,爬虫的是程序对应的字符串。为避免爬虫失败,要进行UA伪装:让爬虫对应的请求载体身份标识伪装成某一款浏览器
import requests
#UA伪装:将对应的User-Agent封装到字典中,赋值为某款浏览器对应的字符串身份标识
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0'
}
#step-1:指定url,以字符串形式
url = 'https://www.sogou.com/web' #只需要简洁的域名,到query后面的搜索词即可
#需要设置动态搜索词,处理url携带的参数,封装到字典中
Keyword = input('enter a word:')
param = {
'query':Keyword
}
#step-2:发起请求
response = requests.get(url = url,params = param,headers = headers) #get发起请求时,请求对应的url有参数,参数可以赋值到params,头信息指定为headers
#step-3:获取响应数据
page_text = response.text
#step-4:持久化存储
fileName = Keyword + '.html'
with open(fileName,'w',encoding = 'utf-8') as fp:
fp.write(page_text)
print(fileName,'保存成功')

例子3:破解百度翻译

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
#页面会局部刷新,需要捕获ajax
#ajax是不用重启或刷新页面,也能加载出页面新的东西
#对应的是POST请求(携带了参数),响应数据是一组json数据
import requests
import json #存储到json文件需要调用
#step-1:指定url,从抓包工具中捕获
post_url = 'https://fanyi.baidu.com/sug'
#step-2:UA伪装(之后所有的爬虫都需要)
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0'
}
#step-3:post请求参数处理(同get请求一致)(发起请求所对应的url有参数才需要处理)
#动态处理
word = input('enter a word:')
data = {
'kw':word
}
#step-4:发起请求
response = requests.post(url = post_url,data = data,headers = headers)
#data是封装url携带参数的字典
#step-5:获取响应数据,此处为json数据,如果直接用response.text获取的是字符串类型的json串,这样也可以。json()方法返回的是obj对象,不是任何时候都适用,除非确认响应数据是json类型的才能使用。
dic_obj = response.json()
print(dic_obj)
#step-6:持久化存储到json文件中
fileName = word + '.json'
fp = open(fileName,'w',encoding = 'utf-8')
json.dump(dic_obj,fp = fp,ensure_ascii = False)
print('over')
#最后可以得到翻译结果

例子4:爬取豆瓣电影分类排行榜

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
import requests
import json
#step-1:指定url
url = 'https://movie.douban.com/j/chart/top_list'
#若url携带参数,需封装到字典中,问号及之后的内容为参数,get请求用params,psot请求用data
param = {
'type': '24',
'interval_id': '100:90',
'action': '',
'start': '0', #从库中的第几部电影去取,这些参数可以自己改,是从0开始的
'limit': '20', #一次取出的个数
}
#step-2:UA伪装
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0'
}
#step-3:post请求参数处理
response = requests.post(url = url,data = data,headers = headers)
#step-4:获取响应数据,左边的名字是自己取的
list_data = response.json()
#step-5:持久化存储到json文件中
fp = open('./douban.json','w',encoding = 'utf-8')
json.dump(list_data,fp = fp,ensure_ascii = False)
print('over')
fp.close() #要关闭了才能查看

例子5:爬取肯德基餐厅查询

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
#发起请求后URL如果发生变化,说明不是ajax请求,URL不变说明是ajax请求
import requests
#step-1:指定url
url = 'http://www.kfc.com.cn/kfccda/ashx/GetStoreList.ashx?op=keyword'
#此处问号后面的参数是有用的,就不需要像例子4一样删掉
#若url携带参数,需封装到字典中,问号及之后的内容为参数,get请求用params,psot请求用data
data = {
'cname':'',
'pid':'',
'keyword':'北京',
'pageIndex':'1',
'pageSize':'10',
}
#step-2:UA伪装
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0'
}
#step-3:POST请求参数处理
response = requests.post(url = url,data = data,headers = headers)
#step-4:获取响应数据,左边的名字是自己取的
page_text = response.text
#step-5:持久化存储
with open('./kfc.html','w',encoding = 'utf-8') as fp:
fp.write(page_text)
print('over')

例子6:爬取国家药品监督管理总局中基于中华人民共和国化妆品生产许可证相关数据

1
2
3
4
5
6
7
8
9
10
11
#因为网页已经全面更新,所以这个案例没法做,但从里面学会了“如何批量获取json数据中的关键信息”
id_list = [] #先定义一个空的仓库,用来储存企业的id
##这一步将POST请求参数处理和获取响应数据代码合在一起,分开跟之前一样
json_ids = requests.post(url = url,data = data,headers = headers).json()
for dic in json_ids['list']: #遍历json_ids['list']中的每个元素(字典)
id_list.append(dic['ID']) #把每个dic字典的'ID'的值放入id_list中
#要取出id封装到字典中
for id in id_list:
data = {
'id':id
}

数据解析

数据解析原理

解析的局部文本内容都会在标签之间或标签对应的属性中进行存储,用于聚焦爬虫,步骤位于获取响应数据后

1、进行指定标签的定位

2、提取(解析)标签或者标签对应属性中存储的数据值

数据解析分类

正则

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
#常用正则表达式
#时代在进步,零基础还是让ai写zh
"""
单字符:
. : 除换行以外所有字符
[] :[aoe] [a-w] 匹配集合中任意一个字符
\d : 数字[0-9]
\D : 非数字
\w : 数字、字母、下划线、中文
\W : 非\w
\s:所有的空白字符,包括空格、制表符、换页符等,等价于[\f \n \r \t \v]
\S : 非空白
数量修饰:
* : 任意多次 >=0
+ : 至少一次 >=1
? : 可有可无 0次或者1次
{m} :固定m次 hello{3,}
{m,} :至少m次
{m,n} :m-n次
边界:
$ :以某某结尾
^ : 以某某开头
分组:
(ab)
贪婪模式 :.*
非贪婪(惰性)模式 :.*? #匹配最短的
re.I : 忽略大小写
re.M : 多行匹配
re.S : 单行匹配
re.sub(正则表达式,替换内容,字符串)
"""
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#正则练习
import re
#提取出pythhon
key = "javapythonc++php"
re.findall('python',key)[0]
#提取出hello world
key = "<html><h1>hello world<h1></html>"
re.findall('<h1>(.*)<h1>',key)[0]
#提取170
string = '我喜欢身高为170的女孩'
re.findall('\\d+',string)
#提取出http://和https://
key = 'http://www.baidu.com and https://boob.com'
re.findall('https?://',key)
#提取出hello
key = 'lalala<hTml>hello</HtMl>hahah'#输出<hTml>hello</HtMl>
re.finda1l('<[Hh][Tt][mM][lL]>(.*)</[Hh][Tt][mM][1L]>',key)
#提取出hit.
key = 'bobo@hit.edu.com' #想要匹配到hit.
re.findall('h.*?\\.',key)
#匹配sas和saas
key = 'saas and sas and saaas'
re.findall('sa{1,2}s',key)
1
2
3
4
5
6
7
8
#例子:爬取网页中的图片(视频课的案例网站下架了,这里可以在百度随便找一篇百家号帖子,对里面的图片点击右键查看链接,单独打开该链接,如果链接中仅包含一张图片,则符合此次练习)
import requests
url = 'https://pics5.baidu.com/feed/a686c9177f3e670943b8a40d0391b83af9dc5561.jpeg@f_auto?token=ac1a9f005bed735ea8b915db9e8a6f46&s=FD3616D09E0B6A47430B19C10300E098'
#content返回的是二进制形式的图片数据
#text字符串 content二进制 json()对象
img_data = requests.get(url = url).content
with open('./picture.jpg','wb') as fp:
fp.write(img_data)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#爬取某页面中所有的图片(视频课的案例网站下架了,这里仍以百家号帖子做练习,但没法练习翻页)
import requests
import re

url = 'https://baijiahao.baidu.com/s?id=1675547469620726703&wfr=spider&for=pc'

headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/139.0.0.0 Safari/537.36 Edg/139.0.0.0'
#使用通用爬虫对url对应的一整张页面进行爬取
page_text = requests.get(url = url,headers = headers).text
#使用聚焦爬虫将页面中所有的图片进行提取/解析
#先将对应的整串div复制下来 <div class="_1NCGf"><img src="https://pics5.baidu.com/feed/c995d143ad4bd113cffa4ece647183084afb0578.jpeg@f_auto?token=2f5a737548dcfcd70c1a6dec2032ced9" width="1200" class="_1g4Ex _1i_Oe "><span class="bjh-image-caption">透漏出的中国建筑特点是...</span><!--30--></div>
#接下来可以问ai:用python的正则表达式提取出代码中的img标签
pattern = r'<img[^>]*>'

img_tags = re.findall(pattern, page_text,re.S)
for img in img_tags:
print(img)

bs4

xpath(重点)

作者

LxxCandy

发布于

2025-08-11

更新于

2025-10-25

许可协议

评论