1 2 3 4

爬虫~requests

1 爬虫介绍

# 1 本质:模拟发送http请求(requests)----》解析返回数据(re,bs4,lxml,json)---》入库(redis,mysql,mongodb)
# 2 app爬虫:本质一模一样
# 3 为什么python做爬虫最好:包多,爬虫框架:scrapy:性能很高的爬虫框架,爬虫界的django,大而全(爬虫相关的东西都集成了)
# 4 百度,谷歌,就是个大爬虫  在百度搜索,其实是去百度的服务器的库搜的,百度一直开着爬虫,一刻不停的在互联网上爬取,把页面存储到自己库中
# 5 全文检索:全文检索


# 10 你公司里可以做项目,爬虫爬回来的(律师行业),搭一个搜索网站(app,小程序),
# 11 医疗行业:造药企业,头孢类的
# 12 爬简历:简历库


#面试很重要:http协议(80%被问到)
# 特点
(1)应用层协议(mysql,redis,mongodb:cs架构的软件:Navicat,python代码:pymysql,都是mysql客户端--socket:自己定制的协议----》服务端)(docker,es---》http(resful)---》服务端)
(2)基于请求-响应模式:
		客户端主动发起请求---》服务端才能响应   (服务端不能主动推送消息:轮询,长轮询,websocket协议:主动推送消息)
(3)无状态保存(cookie,session,token:)
(4)无连接:发送一次请求,响应完就断开,性能影响(http协议版本:0.9,1.1:多次请求,共用一个socket连接,2.0:
    一次请求,可以携带多个http请求)
    
# http请求:请求首行,请求头,请求体
	-127.0.0.1/name=lqz&age=18:请求首行
  -post请求请求体中放数据:name=lqz&age=18  放在请求体中
  	-post请求,可以这样发么:127.0.0.1/name=lqz&age=18,django数据requtes.GET
    -放在体中的:request.POST
    -请求体的格式(编码格式):
      urlencode:name=lqz&age=18   ---》request.POST
      json:{name:lqz,age:18}     ---->request.POST取不出来(为什么?django框架没有做这个事)
      formdata:传文件,5g大文件,    ----》request.POST
# http响应:
	# 响应首行:状态码:1,2,3,4,5   301和302的区别
  # 响应头:key:value:背几个响应头
  	-cookie:
    -cache-control:缓存控制
  # 响应体:
  	html,json
    
# 浏览器调试
	-右键--》调试模式
  -elements:响应体,html格式
  -console:调试窗口(js输出的内容,在这能看到)
  -network:发送的所有请求,all  xhr:ajax请求
    
    

2 requests模块

# 1 模块:可以模拟发送http请求,urlib2:内置库,不太好用,繁琐,封装出requests模块,应用非常广泛(公司,人)
# 2 pip3 install requests
# 3 小插曲:requests作者,众筹换电脑(性能跟不上了),捐钱(谷歌公司捐了),2 万 8 千美元,买了游戏设备,爆料出来,骗捐,辟谣
# 1 request模块基本使用

import requests

# # 发送http请求
# # get,delete,post。。本质都是调用request函数
# ret=requests.get('https://www.cnblogs.com')
# print(ret.status_code) # 响应状态码
# print(ret.text)  # 响应体,转成了字符串
# print(ret.content) # 响应体,二进制
# ret=requests.post()\
# ret=requests.request("get",)
# ret=requests.delete()

# 2 get 请求带参数
# 方式一
# ret = requests.get('https://www.baidu.com/',
#                    headers={
#                        # 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.149 Safari/537.36',
#                        'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.132 Safari/537.36'
#                    })
# print(ret.text)
# 方式2(建议用方式二)中文会自动转码
# ret=requests.get('http://0.0.0.0:8001/',params={'name':"美女",'age':18})
# print(ret.text)


# 3 带headers
# ret = requests.get('http://0.0.0.0:8001/?name=%E7%BE%8E%E5%A5%B3',
#                    headers={
#                        # 标志,什么东西发出的请求,浏览器信息,django框架,从哪取?(meta)
#                        'User-Agent': 'request',
#                        # 上一个页面的地址,图片防盗链
#                        'Referer': 'xxx'
#                    })
# print(ret)

# 图片防盗链:如果图片的referer不是我自己的网站,就直接禁止掉
# <img src="https://www.lgstatic.com/lg-community-fed/community/modules/common/img/avatar_default_7225407.png">


# 4 带cookie,随机字符串(用户信息:也代表session),不管后台用的token认证,还是session认证
# 一旦登陆了,带着cookie发送请求,表示登陆了(下单,12306买票,评论)
# 第一种方式
# ret = requests.get('http://0.0.0.0:8001/?name=%E7%BE%8E%E5%A5%B3',
#                    headers={
#                        'cookie': 'key3=value;key2=value',
#                    })
# 第二种方式
# ret = requests.get('http://0.0.0.0:8001/?name=%E7%BE%8E%E5%A5%B3',
#                    cookies={"islogin":"xxx"})
# print(ret)

# 5 发送post请求(注册,登陆),携带数据(body)
#data=None, json=None
# data:urlencoded编码
# ret=requests.post('http://0.0.0.0:8001/',data={'name':"lqz",'age':18})
# json:json编码
# import json
# data=json.dumps({'name':"lqz",'age':18})
# ret=requests.post('http://0.0.0.0:8001/',json=data)
# print(ret)
# 注意:编码格式是请求头中带的,所有我可以手动修改,在headers中改

# 6 session对象
# session=requests.session()
# # 跟requests.get/post用起来完全一样,但是它处理了cookie
# # 假设是一个登陆,并且成功
# session.post()
# # 再向该网站发请求,就是登陆状态,不需要手动携带cookie
# session.get("地址")


# 7 响应对象
# print(respone.text)   # 响应体转成str
# print(respone.content) # 响应体二进制(图片,视频)
#
# print(respone.status_code) # 响应状态码
# print(respone.headers) # 响应头
# print(respone.cookies) # 服务端返回的cookie
# print(respone.cookies.get_dict()) # 转成字典
# print(respone.cookies.items())
#
# print(respone.url)  # 当次请求的地址
# print(respone.history) # 如果有重定向,放到一个列表中
# ret=requests.post('http://0.0.0.0:8001/')
# ret=requests.get('http://0.0.0.0:8001/admin')
# #不要误解
# ret=requests.get('http://0.0.0.0:8001/user')
# print(ret.history)

# print(respone.encoding) # 编码方式

#response.iter_content() # 视频,图片迭代取值
# with open("a.mp4",'wb') as f:
#     for line in response.iter_content():
#         f.write(line)


# 8 乱码问题
# 加载回来的页面,打印出来,乱码(我们用的是utf8编码),如果网站用gbk,
# ret.encoding='gbk'
# ret=requests.get('http://0.0.0.0:8001/user')
# # ret.apparent_encoding当前页面的编码
# ret.encoding=ret.apparent_encoding


# 9 解析json
# 返回数据,有可能是json格式,有可能是html格式
# ret=requests.get('http://0.0.0.0:8001/')
# print(type(ret.text))
# print(ret.text)
#
# a=ret.json()
# print(a['name'])
# print(type(a))

# 10 使用代理
# 正向代理
# django如何拿到客户端ip地址 META.get("REMOTE_ADDR")
# 如何去获取代理,如何使用(用自己项目验收)
# 使用代理有什么用
# ret=requests.get('http://0.0.0.0:8001/',proxies={'http':'地址'})
# print(type(ret.text))
# print(ret.text)

# 11 异常处理
# 用try except捕获一下 就用它就型了:Exception

# 12 上传文件(爬虫用的比较少,后台写服务,)
# file={'myfile':open("1.txt",'rb')}
# ret=requests.post('http://0.0.0.0:8001/',files=file)
# print(ret.content)


# 认证,处理ssl(不讲了)

3 代理

## 代理
# 网上会有免费代理,不稳定

# 使用代理有什么用?
# drf:1分钟只能访问6次,限制ip
# 每次发请求都使用不同代理,random一下
# 代理池:列表,其实就是代理池的一种
import requests
# ret=requests.get('https://www.cnblogs.com/',proxies={'http':'222.85.28.130:40505'})

#高匿:服务端,根本不知道我是谁
#普通:服务端是能够知道我的ip的
# http请求头中:X-Forwarded-For:代理的过程
# ret=requests.get('http://101.133.225.166:8080',proxies={'http':'222.85.28.130:40505'})
# ret=requests.get('http://101.133.225.166:8080',proxies={'http':'114.99.54.65:8118'})
# print(ret.text)

4 爬视频

############
# 2 爬取视频
#############
#categoryId=9 分类id
#start=0 从哪个位置开始,每次加载12个
# https://www.pearvideo.com/category_loading.jsp?reqType=5&categoryId=9&start=0

import requests
import re
ret=requests.get('https://www.pearvideo.com/category_loading.jsp?reqType=5&categoryId=9&start=0')
# print(ret.text)
# 正则取解析
reg='<a href="(.*?)" class="vervideo-lilink actplay">'
video_urls=re.findall(reg,ret.text)
print(video_urls)
for url in video_urls:
    ret_detail=requests.get('https://www.pearvideo.com/'+url)
    reg='srcUrl="(.*?)",vdoUrl=srcUrl'
    mp4_url=re.findall(reg,ret_detail.text)[0] #type:str
    # 下载视频
    video_content=requests.get(mp4_url)
    video_name=mp4_url.rsplit('/',1)[-1]
    with open(video_name,'wb') as f:
        for line in video_content.iter_content():
            f.write(line)




5 自动登录网站

############
# 3 模拟登陆某网站
#############

import requests

ret = requests.post('http://www.aa7a.cn/user.php',
                    data={
                        'username': '616564099@qq.com',
                        'password': 'lqz123',
                        'captcha': 'f5jn',
                        'remember': '1',
                        'ref': 'http://www.aa7a.cn/',
                        'act': 'act_login',
                    })
cookie=ret.cookies.get_dict()
print(cookie)
# 如果不出意外,咱么就登陆上了,再向首页发请求,首页返回的数据中就有616564099@qq.com
ret1=requests.get('http://www.aa7a.cn/',cookies=cookie)
# ret1=requests.get('http://www.aa7a.cn/')

print('616564099@qq.com' in ret1.text)


# 秒杀小米手机,一堆小号
# 定时任务:一到时间,就可以发送post请求,秒杀手机


# 以后碰到特别难登陆的网站,代码登陆不进去怎么办?

# 之所以要登陆,就是为了拿到cookie,下次发请求(如果程序拿不到cookie,自动登陆不进去)
# 就手动登陆进去,然后用程序发请求

1 http 0.9 1.1 和2.0的区别

2 301和302的区别

3 正向代理和反向代理

https://www.cnblogs.com/liuqingzheng/p/10521675.html

4 伪静态

5 把爬视频的改成线程池提高爬取速度,加入代理

posted @ 2020-05-31 22:03  ^更上一层楼$  阅读(164)  评论(0编辑  收藏  举报