网络爬虫实战练习
网络爬虫练习
- 正则获取红牛数据
- 获取糗图百科的图片
- 爬取优美图库高清图片
- 爬取梨视频
正则获取红牛数据
思路
# 1.判断数据加载方式,打开网络源地址,查找数据,发现为直接加载 # 2.进入network,查找url地址、请求方式或请求头等信息 # 3.执行代码筛选
执行代码
# 调用模块 import requests import json import re # 请求数据 res=requests.get('http://www.redbull.com.cn/about/branch') res_text=res.text # 获取公司名,去除多余符号 h2_list=re.findall('<h2>(.*?)<',res_text) # 获取具体地址,去除多余符号 p_add=re.findall("mapIco'>(.*?)<",res_text) # 获取邮箱,去除多余符号 p_mail=re.findall("mailIco'>(.*?)<",res_text) # 获取电话,去除多余符号 p_phone=re.findall("telIco'>(.*?)<",res_text) # 拉链方法,生成一个迭代器 res2=zip(h2_list,p_add,p_mail,p_phone) # 循环输出迭代器 for i in res2: print(i)
获取糗图百科图片
思路
1.查看图片加载方式,发现为直接加载
2.所以判断:可以直接向本网页发送get请求,获取数据信息 3.打开network查看url地址,请求方式 4.循环获取每个图片的url地址 5.像图片地址发送请求,获取图片信息后写入文件
代码
# 调用模块 import requests from bs4 import BeautifulSoup import os # 判断是否存在蔬菜文件夹 if not os.path.exists(r'图片'): # 创建蔬菜文件 os.mkdir(r'图片') img_page=input('亲输入你要的页面:') # 发送请求 res=requests.get(url='https://www.qiushibaike.com/imgrank/page/%s'%img_page) # 构造解析对象 soup=BeautifulSoup(res.text,'lxml')
查看获取数据的内容
print(soup.text)
或者在网络源码中查看更直观
经过观察,所有img标签的class都为illustration,可以class名来索引图片
img_info=soup.select('img.illustration') print(img)
经入for循环依次获取各个img的src地址,在向src地址发送个体请求才可以再获得数据
# 循环获取图片信息 for img in img_info: # 获取图片地址 img_info_src = img.get('src') # 图片地址不完整,所以要整合 img_info_src='https:'+img_info_src # 向图片地址发送请求 res2=requests.get(img_info_src) # 获取图片名,输入图片保存 with open(r'图片\%s.jpg'%img_info_src.rsplit('/')[-1].strip('.jpg'),'wb') as f: # 以二进制格式写入 f.write(res2.content)
执行结果:
爬取
思路
1.打开网址查看数据加载方式,方法是打开网络源码查看数据是否存在
2.存在为直接加载,不存在为js动态申请,发现数据为js动态加载
3.打开network查看url地址,请求方式
4.获取首页所有详细页面地址后,执行循环向详细页面地址发送请求
5.进入详细页面时,查看图片加载方式
6.network查看url地址,请求方式,请求体或请求头文件
7.期间还需要观察数据之间的联系,为了方便索引取值
8.向图片地址发送请求获取图片信息
代码
# 调用模块 import requests import os from bs4 import BeautifulSoup # 判断文件是否存在 if not os.path.exists(r'高清'): os.mkdir(r'高清') # 发送请求 res=requests.get('https://www.umei.cc/meinvtupian/rentiyishu/index.htm')
当前获取的信息中包含图片是缩略图,但我们要的是高清图
# 调用模块 import requests import os from bs4 import BeautifulSoup # 判断文件是否存在 if not os.path.exists(r'高清'): os.mkdir(r'高清') # 发送请求 res=requests.get('https://www.umei.cc/meinvtupian/rentiyishu/index.htm') # 获取解析对象 soup=BeautifulSoup(res.text,'lxml') # 获取各个图片详细页面 img_info=soup.select('.TypeList .TypeBigPics') # 循环取值 for a in img_info: # 获取地址 img_href=a.get('href') print(img_href)
获取地址后发现地址不完整
# 是地址完整 img_href="https://www.umei.cc/"+img_href print(img_href)
res2=requests.get(img_href) # 定义解析对象 soup2=BeautifulSoup(res2.text,'lxml') # 获取class为.imageBody标签的子img标签 img_src=soup2.select('.ImageBody img') print(img_src)
for img_for_src in img_src: # 获取图片地址 img_src_real=img_for_src.get('src') # 像地址发送请求 res3=requests.get(img_src_real)
# 命名文件,二进制写入,命名规则为网址末尾从右往左
file_path = os.path.join(r'高清',img_src_real[-10:])
# 二进制写入,
with open(file_path,'wb') as f:
# 将文件写入
f.write(res3.content)
print(img_src_real[-10:]+'爬取成功')
time.sleep(1)
执行结果
防爬措施之防爬链
什么是防爬链
效验当前请求,如果为本网站则允许,不是本网站不允许
解决措施
在请求头中加入,referer键值对
爬取梨视频
思路
1.打开网址查看数据加载方式,方法是打开网络源码查看视频数据是否存在
2.存在为直接加载,不存在为js动态申请,发现数据为js动态加载
3.打开network查看url地址,请求方式,视频文件多为get请求
4.获取首页所有详细页面地址后,执行循环向详细页面地址发送请求
5.进入详细页面时,查看视频加载方式
6.network查看url地址,请求方式,请求体或请求头文件
systemTime
srcUrl
7.获取信息后,发现不是视频数据
8.再对请求结果的观察中发现真实地址与请求结果地址有相似的地方,但也有不同的地方
9.通过特定的值将请求结果地址替换为真实地址,利用视频ID与systemTIme进行替换,就可以发送求获得视频
10.梨视频存在防爬链,需要在请求返回值中查找referer键值对
11.将referer键值对,作为请求头加入请求
12.向视频的地址发送请求获取视频信息
13.最好设置时间间隔,不要要频繁
代码
# 调用模块 import requests from bs4 import BeautifulSoup import os # 发送get请求网址 res=requests.get('https://www.pearvideo.com/category_9') # 构造解析对象 soup=BeautifulSoup(res.text,'html')
发现视频地址都在class为categoryem的li标签中
# 获取li列表中a链接标签 li_class=soup.select('.categoryem a.vervideo-lilink') # 循环获取视频地址 for a_href in li_class: # 获取网址具体地址 a_list_href=a_href.get('href')
# 获取网络ID
video_id=a_list_href.split('_')[-1]
进入详情页时发现,视频为js动态加载,查看network信息,url,请求方式
mrd:为随机数不用在意。contld值正好为video_id
res2=requests.get('https://www.pearvideo.com/videoStatus.jsp?contId=1742106&mrd=0.5963827104022161', headers={"Referer": "https://www.pearvideo.com/video_1742106"} ) print(res2.text)
但是输入该网址后,没有视频内容,所以不是具体视频地址
经过后期的查找,上述视频真实地址,经过观察发现两个网址的不同处为cont-1742106和1632314469227,1742106也正是之前的video的ID号,所以只要进行替换便可获取数据
# 发送请求 res2=requests.get('https://www.pearvideo.com/videoStatus.jsp?', # 请求体确定视频 params={"contId": video_id}, # 请求头输入防爬链 headers={"Referer": "https://www.pearvideo.com/video_%s"%video_id}, ) # 因为是json格式,使用json转义对应数据,获取假的视频地址 fake_href=res2.json()["videoInfo"]["videos"]['srcUrl']
在观察时我们可以发现,请求获取的数据中systemTime就是冲突值,可以一次为替换
# 获取冲突值 systemtime=res2.json()["systemTime"] # 将假地址变成真地址 real_href=fake_href.replace(systemtime,'cont-%s'%video_id) # 发送请求 res4=requests.get(real_href, # 请求体确定视频 params={"contId": video_id}, # 请求头输入防爬链 headers={"Referer": "https://www.pearvideo.com/video_%s" % video_id}, ) # 路径拼接 file_path=os.path.join(r'视频',real_href[-8:]) # 打开路径,以二进制写入 with open(file_path,'wb') as f: # 写入数据 f.write(res4.content) # 提示成功 print("请下载成功") # 等待时间 time.sleep(1)