爬虫的基本原理、requests模块、模拟登陆网站、爬取视频网站、cookie池和代理池、正向代理和反向代理
1、爬虫的定义:
向网站发起请求,获取资源后分析并提取有用数据的程序
2、爬虫的基本流程
(1)发送请求:
使用http库向目标站点发起http请求,即发送一个Request Request包含:请求头、请求体等
(2)获取响应内容:
如果服务器能正常响应,则会得到一个Response Response包含:html,json,图片,视频等
(3)解析内容:
解析html数据:正则表达式,第三方解析库如Beautifulsoup,pyquery等 解析json数据:json模块 解析二进制数据:以b的方式写入文件
(4)保存数据:
数据库 文件
3、cookie池和代理池:
cookie池:可能某些网站设置了访问的频率限制,用来模拟不同的用户进行访问
代理池:用来模拟不同的ip用户对网站进行访问
4、正向代理和反向代理:
正向代理:代理自己,例如FQ(访问谷歌):向某个服务器发请求,服务器再向谷歌发请求,请求数据再返回给自己。
反向代理:向服务器发请求(一个ip地址),发送到nginx(反向代理服务器),再发送到后台服务器上(可能有很多台,但看看起来就是一台)。
5、模拟登陆:
# 设置请求头 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36' } # 登录的post请求,以及携带的参数 res = requests.post( 'http://www.aa7a.cn/user.php', headers=headers, data={ 'username':'1640808365@qq.com', 'password':'147258369..', 'captcha': 'ubw3', 'remember': 1, 'ref': 'http://www.aa7a.cn/', 'act': 'act_login' }) # 登录成功请求结果中得到的cookies cookie = res.cookies.get_dict() # 验证登录成功的请求页面是否包含登录信息 res = requests.post('http://www.aa7a.cn/', headers=headers, cookies=cookie) if '1640808365@qq.com' in res.text: print('登陆成功!') else: print('登录失败!')
6、 爬取梨视频案例:
import re # 爬取梨视频步骤: # 1.先获取要爬取内容的目标url # https://www.pearvideo.com/category_loading.jsp?reqType=5&categoryId=3&start=36&mrd=0.762001536578264&filterIds=1625871,1625877,1625918,1625694,1625682,1625684,1625687,1625674,1625664,1625661,1625648,1625645,1625634,1625614,1625604 # 2.分析需要得到的链接 res = requests.get('https://www.pearvideo.com/category_loading.jsp?reqType=5&categoryId=3&start=36') # 3.利用正则得到想要匹配的内容 # <a href="video_1625614" class="vervideo-lilink actplay"> reg_txt = '<a href="(.*?)" class="vervideo-lilink actplay">' obj = re.findall(reg_txt, res.text) # print(obj) # 4.拼接需要访问的路径:如:https://www.pearvideo.com/video_1625614 for url in obj: res_url = 'https://www.pearvideo.com/'+url # 得到的视频页面 res_v = requests.get(res_url) # 5、匹配到最终的视频地址(列表) obj_v = re.findall('srcUrl="(.*?)"', res_v.text) # print(obj_v) obj1 = requests.get(obj_v[0]) # 切分出视频名称 name = obj_v[0].rsplit('/', 1)[1] print(name) # 循环写入文件中,iter_content():二进制流 with open(name, 'wb') as f: for line in obj1.iter_content(): f.write(line)