Requests模块初识
一小爬虫初见requests:
url='https://www.sogou.com/web?query=周杰伦'
resp=requests.get(url)
print(resp.text)
步骤:
先找到需要爬取的url,然后用requests的get方法获取url的响应response就可得到该页面的数据
User-Agent的使用:
先看一段简短的爬虫代码:
kw=input("")
url=f'https://www.sogou.com/web?query={kw}'
resp=requests.get(url)
print(resp.text)
但是运行出来啥也没有,很明显只能是被反爬拦截了。
因此我们要做一个伪装,我们之所以被拦截是因为该服务器把我们给认出来了/(ㄒoㄒ)/~~,直接拒之门外好吧!
但是莫得关系我们直接摇身一变伪装成浏览器,所以咱们就加一个请求头中的User-Agent
headers={
"User-Agent": 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36'
}
然后再在获取响应的过程中加上这个请求头就行了
resp=requests.get(url,headers=headers)
就大功告成了
爬取百度翻译的练习:
这是一个客户端渲染的一个网站因此第一次请求中确实是没有数据只有html骨架的
因此我们得去找第二次请求中的数据,而第二次一般是在XHR类型中
然后一个一个找就找到了第二次请求为sug
然后找到url复制下来爬取即可,但是这是是有输入的所以显然应当是一个post请求,所以这里的接受响应有所区别,还有data参数接受输入数据
word=input("please input word you want to translate:")
data={
"kw":word
}
resp=requests.post(url,data=data)
这样就大功告成了
re模块
正则表达式回顾:
元字符: 具有固定含义的特殊符号 常⽤元字符
. 匹配除换⾏符以外的任意字符
w 匹配字⺟或数字或下划线
s 匹配任意的空⽩符
d 匹配数字
量词: 控制前⾯的元字符出现的次数
贪婪匹配和惰性匹配
n 匹配⼀个换⾏符
t 匹配⼀个制表符
^ 匹配字符串的开始
$ 匹配字符串的结尾
W 匹配⾮字⺟或数字或下划线
D 匹配⾮数字
S 匹配⾮空⽩符
a|b 匹配字符a或字符b
() 匹配括号内的表达式,也表示⼀个组
[...] 匹配字符组中的字符
[^...] 匹配除了字符组中字符的所有字符
量词: 控制前⾯的元字符出现的次数
* 重复零次或更多次
+ 重复⼀次或更多次
? 重复零次或⼀次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次
贪婪匹配和惰性匹配
.* 贪婪匹配
.*? 惰性匹配
最常用的!!!!!
其他正则都不说了,基本不用。。。除了最后两个贪婪匹配与惰性匹配
贪婪指的是尽可能多的去匹配
而惰性是尽可能少的去匹配
这些数据解析的模块基本都是处理超文本文件的,所以我们用几个超文本文件的案例来解释一下这俩正则表达式
str: 玩⼉吃鸡游戏, 晚上⼀起上游戏, ⼲嘛呢? 打游戏啊
reg: 玩⼉.*?游戏 此时匹配的是: 玩⼉吃鸡游戏
reg:玩⼉.*游戏 此时匹配的是: 玩⼉吃鸡游戏, 晚上⼀起上游戏, ⼲嘛呢? 打游戏
re的匹配规则:
obj = re.compile(r"d+") #预加载正则表达式
lis=obj.finditer("www.43468.dasd151.dasd185151")#匹配url中html符合的数据
for i in lis:
print(i.group()) #由于finditer匹配是返回的是迭代器所以用group方法得到数据
print(lis)
re中匹配方法如下:
'''
#findall:匹配字符串中所有符合其正则的子字符串并返回列表
lis=re.findall(r'www.*.com','www.4399.com')
print(lis)
#finditer最常用重要
#finditer :匹配字符串中所有符合其正则的子字符串并返回迭代器
it=re.finditer(r'd+','www.4399.com.54184')
print(it)
for i in it:
print(i,end="group可去掉数据其他的东西")
print(i.group())
#search,找到一个结果就返回其余与finditer类似
s=re.search(r'd+','www.4399.com.54184')
print(s.group())
#match从头开始匹配其余与finditer类似
s=re.match(r'd+','www.4399.com.54184')
print(s.group())
'''
还有一个非常非常重要的一个东西总之re你就必须得用好吧! 呐呐呐就是把匹配的字段取别名以便用group取出是可以只要有别名的那一段数据
s = """
移动
中国联
中通
联通
中国联通
中国通
"""
obj = re.compile(r"(?P.*?)", re.S) #re.S是让.能够匹配换行符防止匹配断掉
ls=obj.finditer(s)
for i in ls:
print(i.group('Name'),i.group('id'),i.group('name'))
结果为
三国 10010 移动
⻄游 10010 中国联
⻄记 10010 中通
⻄ 10010 联通
⻄游记 10010 中国联通
记 10010 中国通
爬取电影天堂电影前列排名的下载地址示例:
该需求需要这几个步骤
#定位到2020必看片
#从2020必看片中提取到子页面的地址
#对子页面的链接地址发送请求,拿到下载地址
而进入url可看到
可知该网站有加密所以我们在得到响应的代码中应当加入
resp=requests.get(domain,verify=False) #verify:取消安全验证
并且除此之外如果执行这段代码得到的是一段乱码,而在这些乱码中能够看到该html的编码方式,所以还需要encoding操作resp.encoding='gb2312'
domain="https://dytt89.com/"
resp=requests.get(domain,verify=False)
print(resp.text)
然后就可以根据前面所讲的re去匹配到子页面地址
注意在使用re中的堕落匹配时最前面的html标签一定是要有代表性的,不然就可能匹配到其他地方去了就得不到数据
得到子页面地址后就可以遍历该地址迭代器然后与domain拼接成子页面url然后继续之前类似的操作去获取电影的名字与下载地址即可
#定位到2020必看片
#从2020必看片中提取到子页面的地址
#对子页面的链接地址发送请求,拿到下载地址
import requests
import re
domain="https://dytt89.com/"
resp=requests.get(domain,verify=False) #verify:取消安全验证
resp.encoding='gb2312'
obj1=re.compile(r'>2022必看热片.*?
.*?
',re.S)
obj2=re.compile(r"