爬虫本质、requests模块

一、爬虫本质

步骤:

1、模拟发送http请求(requests)

2、解析返回数据(re,bs4,lxml,json)

3、入库(redis,mysql,mongodb)

 

二、http协议

为什么用python语言做爬虫好,因为用很多包,有爬虫框架scrapy(大而全)

 

http协议是基于tcp/ip协议之上的 应用层协议。(服务端不能主动给客户端发送信息)

mysql、redis、MongoDB都是c/s架构软件。navicat、Python代码(pymysql) 都是mysql的客户端.

docker、es等走的是http协议遵循restful规范再到服务端

mysql、redis、MongoDB等走的是自定义的协议socket到服务端

 

HTTP 1.1和HTTP2.0的区别??

 

HTTP的请求与响应

01、请求

请求首行

请求头

空格

请求体

 

注意:get请求 带的数据 放在请求首行里。如:127.0.0.8000/name=mq&age=18

           post请求 带的数据 放在请求体中 。请求体的格式(编码格式):urlencode(name=mq&age=18)   可以在django框架中的resquest.POST中取出

                                                                                                               :formdata(传文件)                     可以在django框架中的resquest.POST中取出

                                                                                                               :json(name:mq,age:18)       不可以在django框架中的resquest.POST中取出

02、响应

 

响应首行 

响应头

空格

响应体

 

三、浏览器调试

1、右键:调试模式

2、elements 表示响应体是html格式

3、console  表示调试窗口。js输出的内容,能在这里看到

4、network  表示发送的所有请求

四、requests模块(可以模拟发送http请求)

1、安装:命令:pip install requests

2、基本使用

 

 

  01、各种请求方式

 import requests
 r = requests.get('https://www.cnblogs.com')
 r = requests.post('https://www.cnblogs.com', data = {'key':'value'})
 r = requests.put('https://www.cnblogs.com', data = {'key':'value'})
 r = requests.delete('https://www.cnblogs.com')
 r = requests.head('https://www.cnblogs.com')
 r = requests.options('https://www.cnblogs.com')

  02、响应对象

import requests
response = requests.get('https://www.cnblogs.com/kermitjam/')
print(response.text)

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)                                      # 如果有重定向,放到一个列表中.查看上一次请求从哪里来。(图片防盗链)
print(respone.encoding)                                     # 编码方式
print(respone.iter_content())                               # 视频,图片迭代取值



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

  03、get请求 使用

 

import requests
response = requests.get('https://www.cnblogs.com/kermitjam/')
print(response.text)

  001、get请求携带参数

# 方式一:会转码,不推荐
response = requests.get('https://www.baidu.com/s?wd=%E7%BE%8E%E5%A5%B3')

# 方式二:推荐
response = requests.get('https://www.baidu.com/',params={'name':'美女','age':18})

  002、 get请求携带headers头

respone = requests.get('http://127.0.0.1:8000/',params={'name':'美女','age':18},
                   headers={ # 表示:什么东西发出的请求(浏览器信息)。django框架,从哪取?(meta)
                       'User-Agent': 'request',
                       'Referer': 'xxx'      # 表示:如果图片的referer不是自己的网站,就直接禁止掉(图片防盗链)
                   })
print(respone.status_code)

  003、get请求携带cookie

带cookie,随机字符串(用户信息:也代表session),不管后台用的token认证,还是session认证

一旦登陆了,带着cookie发送请求,表示登陆了(下单,12306买票,评论)

# 第一种方式
ret = requests.get('http://127.0.0.1:8000/',params={'name':'美女','age':18},
                   headers={
                       'cookie': 'key3=value;key2=value',
                   })

# 第二种方式
ret = requests.get('http://127.0.0.1:8000/',params={'name':'美女','age':18},
                   cookies={"islogin":"xxx"})       # 比如:cookie = {"islogin":True}
print(ret.status_code)

  04、post请求 携带数据(注册、登录)

方式一、# data:urlencoded编码:
ret = requests.post('http://127.0.0.1:8000/', data={'name': "jeff", 'age': 18})


方式二、# data:json编码
import json
data = json.dumps({'name': "jeff", 'age': 18})
ret = requests.post('http://127.0.0.1:8000/', json=data)
print(ret)
# 注意:编码格式是请求头中带的,所以可以手动修改,在headers中改

 05、session对象

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

print(res)

06、乱码问题

加载回来的页面,打印出来,乱码(因为 :如果网站用的是gbk,我们用的是utf8编码)

ret = requests.get('http://127.0.0.1:8000/')
ret.encoding='gbk'                              # 修改编码

print(ret.apparent_encoding)                    # 当前页面的编码
# ret.encoding = ret.apparent_encoding
print(ret.encoding)
print(ret.apparent_encoding)

07、解析json数据

# 返回数据,有可能是json格式,有可能是html格式
ret=requests.get('http://127.0.0.1:8000/')
# print(type(ret.text))
# print(ret.text)

a=ret.json()
print(a['name'])
print(type(a))

 五、代理

代理简单解释:
	代理其实就是一个中介,A和B本来可以直连,中间插入一个C,C就是中介。
	
高匿:服务端,根本不知道我是谁
普通:服务端是能够知道我的ip的
#http请求头中:X-Forwarded-For:代理的过程

爬虫使用正向代理好处:
	1.突破频率限制。做个代理池,每次请求都是不同的Ip,服务器认为是不同的用户
	2.不会封自己的ip。

正向代理即是客户端代理, 代理客户端, 服务端不知道实际发起请求的客户端.
反向代理即是服务端代理, 代理服务端, 客户端不知道实际提供服务的服务端

代理池:比如列表,实质上也算是一个代理池
注意:网上有免费的代理,但不稳定
drf:1分钟只能访问6次,限制ip
import requests
ret = requests.get('https://www.pearvideo.com/', proxies={'http': '47.115.54.89'})  # 正向代理
print(type(ret.text))
print(ret.text)

 六、上传文件

# 爬虫用的比较少,后台写服务

file = {'myfile': open("1.txt", 'rb')}
ret = requests.post('http://127.0.0.1:8000/', files=file)
print(ret.content)


七、爬梨视频

 

 

 

 

 

 

 

八、

# 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,自动登陆不进去)
# 就手动登陆进去,然后用程序发请求

 

 

 

 

 

 





 

posted @ 2020-04-16 07:01  薛定谔的猫66  阅读(209)  评论(0)    收藏  举报