python学习之爬虫二
1.requests模块中部分函数的介绍
正则表达式的书写,同步处理,异步处理,带参数的处理
import requests # 乌龙事件,没有来联网就去运行整个程序,肯定会报错啊 # 没有联网,该台电脑怎么向目的主机发送请求呢 # from urllib.parse import urlencode # # 在requests模块还为出现前使用的方法 # url='https://www.baidu.com/s?'+urlencode({"wd":"牛超"}) # headers = { # 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36'} # print(url) # response=requests.get(url,headers=headers) # with open('新牛超.html','w',encoding='utf-8')as f: # f.write(response.text) ''' 请求参数params 访问百度搜查安徽工程大学url https://www.baidu.com/s?wd=安徽工程大学&pn=10 对应第二页 https://www.baidu.com/s?wd=安徽工程大学&pn=20 对应第三页 由规律可知页数与pn的值有关 ''' url='https://www.baidu.com/s?' headers = { 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.90 Safari/537.36' } response=requests.get(url,headers=headers,params={"wd":"安徽工程大学",'pn':'20'}) # 此时爬取到网页上的文本文件,再以html的形式保存 # 等价于用文本文档写网页,再用html形式保存 with open('安徽工程大学.html','w',encoding='utf-8')as f: f.write(response.text)
# 异步爬取 # 线程池,限制开设多少个线程,开设的线程即是内存资源 # 导入线程池模块 import requests import re import uuid # 导入线程池模块 from concurrent.futures import ThreadPoolExecutor pool=ThreadPoolExecutor(50) # 比如开设50个线程同时执行任务 def get_page(url): print(f'开始异步任务:{url}') response = requests.get(url) return response # 2. 解析数据 # *?直接匹配 # 异步请求,初次不显示,浏览器会再次执行JS代码,帮我们二次发送请求 # 这个是时候可以查看网页源代码 '''<video webkit-playsinline="" playsinline="" x-webkit-airplay="" autoplay="autoplay" src="https://video.pearvideo.com/mp4/adshort/20190613/cont-1565846-14013215_adpkg-ad_hd.mp4" style="width: 100%; height: 100%;"></video> ''' def parse_index(res): response=res.result() res = re.findall('<a href="video_(.*?)"', response.text, re.S) # 爬取出全部的id给res # 逐个取出id给m_id,然后与前面的url逐个进行拼接 for m_id in res: detail_url = 'https://www.pearvideo.com/video_' + m_id pool.submit(get_page,detail_url).add_done_callback(parse_detail) # 解析详情页获取视频url def parse_detail(res): response=res.result() movie_url=re.findall('srcUrl="(.*?)"',response.text,re.S)[0] pool.submit(get_page, movie_url).add_done_callback(save_movie) # 保存数据 def save_movie(res): movie_res=res.result() with open (f'{uuid.uuid4()}.mp4','wb')as f: f.write(movie_res.content) print(f'视频下载结束:{movie_res.url}') f.flush() # 刷新 # pool想当于一个开关 if __name__ == '__main__': url='https://www.pearvideo.com/' # 将url给get_page()这个函数,这里写函数名即可 # 异步提交,把视频传给get_page函数,把返回的结果传给save_movie函数 # 往get_page发送异步请求,把结果交给parse_index函数 pool.submit(get_page,url).add_done_callback(parse_index)
''' 关于request模块的讲解 ''' import requests import re #正则模块 import uuid # uuid.uuid4()可以根据时间戳生成一段世界唯一的数字 # 对立视频详情页发送请求,获取响应数据 # respone=requests.get(url='https://www.pearvideo.com/') # print(respone.status_code) # print(type(respone.status_code)) # re.findall('正则匹配规则','解析文本','正则模式') # re.S全局模式(对整个文本进行匹配) # 加?非贪婪匹配 #ctrl f 出现搜索框,在里面可以输入查找条件 #获取主页视频详情页id # .指的是当前位置 # *指的是插查找所有 # 下面指的是提取ID # res=re.findall('<a href="video_(.*?)"',respone.text,re.S) # print(res) # for m_id in res: # detail_url='https://www.pearvideo.com/video_'+m_id # print(detail_url) # 爬虫三部曲: ''' 爬取数据的前提示要先针对一个分析,他们的url形式是什么样的,从而来书写 正则表达式 ''' # 1.发送请求 def get_page(url): response = requests.get(url) return response # 2. 解析数据 # *?直接匹配 # 异步请求,初次不显示,浏览器会再次执行JS代码,帮我们二次发送请求 '''<video webkit-playsinline="" playsinline="" x-webkit-airplay="" autoplay="autoplay" src="https://video.pearvideo.com/mp4/adshort/20190613/cont-1565846-14013215_adpkg-ad_hd.mp4" style="width: 100%; height: 100%;"></video> ''' def parse_index(text): res = re.findall('<a href="video_(.*?)"', text, re.S) # print(res) detail_url_list=[] for m_id in res: detail_url = 'https://www.pearvideo.com/video_' + m_id detail_url_list.append(detail_url) return detail_url_list # 解析详情页获取视频url def parse_detail(text): movie_url=re.findall('srcUrl="(.*?)"',text,re.S)[0] return movie_url # 保存数据 def save_movie(movie_url): response=requests.get(movie_url) with open (f'{uuid.uuid4()}.mp4','wb')as f: f.write(response.content) f.flush()# 刷新 # 正式开始: if __name__ == '__main__': # if _name_=='__main__':# main+回车键 # 1.对主页发送请求 index_res = get_page(url='https://www.pearvideo.com/') # 2.对主页进行解析、获取详情页id detail_url_list=parse_index(index_res.text) # print(detail_url_list) # 3.对每个详情页url发送请求 for detail_url in detail_url_list: detail_res=get_page(url=detail_url) # print (detail_res.text) # 4.解析详情页获取视频URL movie_url=parse_detail(detail_res.text) print(movie_url) # 保存数据 save_movie(movie_url)