1. 爬虫
- 爬虫:通过编写程序来获取互联网上的资源
2. web请求过程剖析
服务器渲染
:在服务器那边直接把数据和html整合
在一起,统一返回给浏览器客户端渲染
:第一次浏览器发出请求,服务器端只返回html骨架
;第二次发送数据请求,服务器端则返回相关数据
;最后数据和html骨架在浏览器端进行整合
,因此叫做客户端渲染。
注意:在页面源代码中,无法看到数据。因此必须熟练使用浏览器抓包工具
。
3. HTTP协议
协议
:两个计算机之间为了能够流畅的进行沟通而设置的一个君子协定。常见的有TCP/IP. SOAP协议
,HTTP协议
,SMTP协议
…HTTP协议
——Hyper Text Transfer Protocol(超文本传输协议),用于从万维网服务器
传输超文本
到本地浏览器
的传送协议。- 请求:
请求行
:包括请求方式(get/post)、请求URL地址、协议请求头
:放一些服务器使用的附加信息
,包括反爬信息,浏览器类型,浏览器对数据的要求。比较重要的参数有:User-Agent
:请求载体的身份标识(即用什么浏览器发送的请求);Referer
:防盗链(即本次请求是从哪个页面来的,用于反爬虫
);cookie
:本地字符串数据信息(包括用户登录信息,发爬虫的token)请求体
:请求的参数
:Token
在计算机身份认证中
是令牌(临时)的意思,在词法分析中是标记
的意思。一般作为邀请、登录系统使用。
- 响应(服务器端返回的格式)
状态行
:协议,状态码(返回请求后状态,比如404,即页面不存在)响应头
:放一些客户端要使用的附加信息响应体
:服务器返回的客户端真正需要的内容
- 请求方式
get
:搜索东西 ,显示提交post
:更改、上传东西等,隐式提交
需要补充get和post的区别?
4.requests模块
requests模块
是python中原生的一款基于网络请求
的模块- 作用:
模拟浏览器发送请求
使用方法:
将以下四个步骤作为requests模块的编码流程
指定url
发起请求
1. requests.get(url, params=)
,发送get
请求,发送的数据必须放在字典
中,通过params
参数进行传递
2. requests.post(url, data=)
,发送post
请求,发送的数据必须放在字典中,通过data
参数进行传递
获取响应数据
- res.url
:获取请求的连接
- res.request
,表示返回的res他的请求的头部信息、url信息、请求方式等
res.json()
将服务器返回的内容直接处理成json()
格式
持久化存储
# 将解码的东西保存到文件中
with open("mybaidu.html", mode="w", encoding='utf-8') as f:
f.write(resp.read().decode("utf-8"))
print("over!")
5. 数据解析
5.1 re解析
正则表达式是一种使用表达式的方式对字符串进行匹配的语法规则
百度百科:regular expression
:正则表达式是对字符串(包括普通字符(例如,a 到 z 之间的字母)和特殊字符(称为“元字符”))操作的一种逻辑公式
,就是用事先定义好的一些特定字符、及这些特定字符的组合,组成一个“规则字符串”
,这个“规则字符串”用来表达对字符串的一种过滤
逻辑。正则表达式是一种文本模式
,该模式描述在搜索文本时要匹配的一个或多个字符串
元字符:具有固定含义的特殊符号
. 匹配除了换行符以外的所有字符
\w (word?)匹配字母、数字、下划线
\s 匹配空白符(space?)
\d digital 匹配数字
\n newline 匹配换行符
\t 匹配制表符
^ 匹配字符串的开始
$ 匹配字符串的结束
大写就是小写的非运算
\W (word?)匹配非字母、数字、下划线
\S 匹配非空白符(space?)
\D digital 匹配非数字
a|b 表示或运算
[...] 字符组,里面放需要匹配的字符,该括号里面的-不表示运算而是范围,
比如1-9a-z
[^...] 除了字符组里面的字符选出来
量词:控制前面的元字符出现的次数
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
贪婪匹配和惰性匹配
惰性匹配
:.*?
:?
起一个尽可能少的*的作用,也就是说,在a.*?b
中,a与b之间出现字符的个数尽可能少
,比如,我爱你/我依然爱你/我就是最爱你的,那么惰性匹配中,则会选择第一个字符串贪婪匹配
:.*,在a.*b
中,a与b之间出现字符的个数尽可能多
,比如,我爱你/我依然爱你/我就是最爱你的,那么贪婪匹配中,则会选择最后一个字符串
爬虫中用的最多的就是惰性匹配
正则表达式前面加r
Python正则表达式前的 r 表示原生字符串(rawstring)
,该字符串声明了引号中的内容表示该内容的原始含义,避免了多次转义造成的反斜杠困扰
。
python的re模块
re.findall(正则,待匹配字段)
,返回的是列表re.finditer
返回的是迭代器,通过group函数拿到迭代器中的内容re.search
找到第一个结果就返回,生成的是一个match对象,拿数据需要.group()re.match
从头开始匹配,如果一开始没有出现待匹配的字符,那么就会报错re.compile(正则)
,预加载正则表达式:简化代码- 从正则匹配的内容中提取想要的
某一部分
,可以采用(?P<标签名>正则表达式)
import re
#findall返回的是列表
lst=re.findall(r'\d+', '我的电话号码是10086,女朋友的电话是1234560')
print(lst)
#finditer返回的是迭代器,通过group函数拿到迭代器中的内容
it=re.finditer(r'\d+', '我的电话号码是10086,女朋友的电话是1234560')
for i in it:
print(i.group())
#search 找到第一个结果就返回,生成的是一个match对象,拿数据需要.group()
se=re.search(r'\d+', '我的电话号码是10086,女朋友的电话是1234560')
print(se.group())
#match 从头开始匹配,如果一开始没有出现待匹配的字符,那么就会报错
se=re.match(r'\d+', '10086,女朋友的电话是1234560')
print(se.group())
#预加载正则表达式:简化代码
obj=re.compile(r'\d+')
lis=obj.findall('我的电话号码是10086,女朋友的电话是1234560')
print(lis)
#将里面的人名拿出来,re.S:让.可以匹配换行符,
#从正则匹配的内容中提取想要的某一部分,可以采用(?P<标签名>正则表达式)
S="""
<div class="jay"><span id="1">郭麒麟</span></div>
<div class="jj"><span id="2">林俊杰</span></div>
<div class="jes"><span id="1">周杰伦</span></div>
<div class="jry"><span id="1">郭富城</span></div>
"""
obj=re.compile(r'<div class=".*?"><span id="\d+">(?P<name>.*?)</span></div>',re.S)
result=obj.finditer(S)
for i in result:
print(i.group("name"))
正则表达式得到想要的内容之后进行输出
.group()
:返回匹配的字符串
.groups()
:返回匹配字符串组成的元组
.groupdict()
:返回字典
,通常结合标签名
使用,将标签名作为字典的键,得到的字符串作为value
。通常我们最后输出的也是这个value
值f=open("data.csv", mode="w", encoding="utf-8")
:打开一个可写文件csv.writer(f)
:写入文件,返回一个迭代对象
.writerow
:写入一行数据.writerows
:写入多行数据
res=obj.finditer(page_content)
#打开一个文件
f=open("data.csv", mode="w", encoding="utf-8")
#准备写入一个文件
csvwriter=csv.writer(f)
for i in res:
# print(i.group("name"))
# print(i.group("year").strip())
# print(i.group("score"))
# print(i.group("num"))
dic=i.groupdict()
dic["year"]=dic["year"].strip()
csvwriter.writerow(dic.values())
结果表示为:
5.2 bs4解析
BeautifulSoup
是一个可以从HTML或XML文件中提取数据的Python库。使用BeautifulSoup解析
请求得到的源代码,能够得到一个 BeautifulSoup 对象
,并能按照标准的缩进格式的结构输出。
基本语法
from bs4 import BeautifulSoup
:加载包page=BeautifulSoup(result.text, "html.parser")
:把页面源代码交给BeautifulSoup进行处理,生成一个bs对象
,后面的参数表示指定html解析器
;page.find(标签,属性=值)
:如果标签唯一,只需一个参数,若有多个相同的标签,需要找唯一的属性值来定位所需要的信息。另外当属性为类选择器中的class
时,与python本身的关键字
相冲突,因此需要改变成class_
或者采用新的参数attrs={"class":"hr_table"}
注意:find生成的仍然也是一个bs对象,因此仍然可以再对find生成的对象进行bs解析page.find_all(标签,属性=值)
:所有满足的数据的行。tds.text
:将bs对象
里面的东西转换出来,拿到被标签标记的内容
。类似于迭代对象的.group()