python爬虫笔记

1. 爬虫

  • 爬虫:通过编写程序来获取互联网上的资源

2. web请求过程剖析

  • 服务器渲染:在服务器那边直接把数据和html整合在一起,统一返回给浏览器
  • 客户端渲染:第一次浏览器发出请求,服务器端只返回html骨架;第二次发送数据请求,服务器端则返回相关数据;最后数据和html骨架在浏览器端进行整合,因此叫做客户端渲染。
    注意:在页面源代码中,无法看到数据。因此必须熟练使用浏览器抓包工具

3. HTTP协议

  • 协议:两个计算机之间为了能够流畅的进行沟通而设置的一个君子协定。常见的有TCP/IP. SOAP协议HTTP协议SMTP协议
  • HTTP协议——Hyper Text Transfer Protocol(超文本传输协议),用于从万维网服务器传输超文本本地浏览器的传送协议。
  • 请求:
    1. 请求行:包括请求方式(get/post)、请求URL地址、协议
    2. 请求头:放一些服务器使用的附加信息,包括反爬信息,浏览器类型,浏览器对数据的要求。比较重要的参数有:User-Agent:请求载体的身份标识(即用什么浏览器发送的请求);Referer:防盗链(即本次请求是从哪个页面来的,用于反爬虫);cookie:本地字符串数据信息(包括用户登录信息,发爬虫的token)
    3. 请求体:请求的参数

:Token计算机身份认证中是令牌(临时)的意思,在词法分析中是标记的意思。一般作为邀请、登录系统使用。

  • 响应(服务器端返回的格式)
    1. 状态行:协议,状态码(返回请求后状态,比如404,即页面不存在)
    2. 响应头:放一些客户端要使用的附加信息
    3. 响应体:服务器返回的客户端真正需要的内容
  • 请求方式
    1. get:搜索东西 ,显示提交
    2. 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()

5.3 xpath解析

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值