python爬虫概述
0x00 python爬虫概述
以豆瓣的选电影模块为例,当查看源代码搜索猫猫的奇幻漂流瓶是搜不到的
这时服务器的工作方式应该是这样的
客户端浏览器第一次访问其实服务器端是返回的一个框架(html代码)
当客户端浏览器第二次通过脚本等方式进行访问时服务器端才返回的数据
通过浏览器自带的工具f12来进行分析,打开netwrok进行抓包,文件格式选择xhr,xhr是一种数据格式,在这里可以看到浏览器的请求和服务端的会用
0x01 request
request库的get和post传参方式
url='www.xxx.com'
#get 和www.xxx.com?id=1是一样的
params={"id":"1"}
request.get(params=params)
#post
data={"id":"1"}
request.post(data=data)
0x02 正则表达式,re
常用预定义字符
\d:匹配数字(0-9)
\D:匹配非数字
\w:匹配字母、数字、下划线
\W:匹配非字母、数字、下划线
\s:匹配空白字符
\S:匹配非空白字符
常用量词
.:匹配任意单个字符(除换行符)
^:匹配字符串开头
$:匹配字符串结尾
*:匹配前一个字符0次或多次
+:匹配前一个字符1次或多次
?:匹配前一个字符0次或1次
[]:匹配括号内的任意一个字符
[^]:匹配非括号内的任意一个字符
|:匹配两个表达式中的任意一个
贪婪匹配:尽可能多的进行匹配
.*
非贪婪匹配:尽可能少的进行匹配
.*?
尽可能多的匹配,匹配了一个
import re
str1="<div>12346</div><div>789456</div>"
pattern=re.compile(r"<div>.*</div>")
result=re.findall(pattern=pattern,string=str1)
print(result)
尽可能少的匹配,匹配了两个
import re
str1="<div>12346</div><div>789456</div>"
pattern=re.compile(r"<div>.*</div>")
result=re.findall(pattern=pattern,string=str1)
print(result
)
re.findall 匹配所有符合正则表达式的内容
re.search 匹配第一次符合正则表达式的内容
re.match 只在开头匹配符合正则表达式的内容,相当于加了一个^
re.finditer 返回一个迭代器,需要循环取出数据
import re
str1="<div>12346</div><div>789456</div>"
#加了括号是采用分组的方式
pattern=re.compile(r"<div>(.*?)</div>")
result=re.finditer(pattern=pattern,string=str1)
for i in result:
print(i.group())
给分组起一个名字
import re
str1="<div>12346</div><div>789456</div>"
#给分组起一个名字
pattern=re.compile(r"<div>(?P<id>.*?)</div>")
result=re.finditer(pattern=pattern,string=str1)
for i in result:
print(i.group("id"))
0x03 re爬取豆瓣top250
1.爬取页面原代码,需要查看源代码是否包含了页面数据,没包含需要进行分析,进行f12,network抓包分析
2.使用re正则匹配数据
3.保存数据
import re
import requests
#下方的正则分别匹配电影名称,评分,评论
pattern=re.compile(r'<div class="item">.*?<span class="title">(?P<name>.*?)</span>.*?<span class="rating_num" property="v:average">(?P<score>.*?)</span>.*?<p class="quote">.*?<span>(?P<comment>.*?)</span>',re.S)#re.S匹配换行符
headers={"User-Agent":
"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Mobile Safari/537.36"}
for id in range(0,46,15):
url = f"https://movie.douban.com/top250?start={id}"
rep = requests.get(url, headers=headers)
result = re.finditer(pattern,rep.text)
with open("2.txt","a+",encoding='utf-8') as f:
for result_list in result:
name=result_list.group("name")
score=result_list.group("score")
comment=result_list.group("comment")
f.write(f"{name},{score},{comment}\n")
在写评论的时候遇到一个问题,一直读不出评论,发现是正则写错了,在p和span标签之间有许多空格
<p class="quote">.*?<span>(?P<comment>.*?)</span>#正确的
<p class="quote"><span>(?P<comment>.*?)</span>#错误的