爬虫介绍及requests模块

爬虫介绍及requests模块

1. 爬虫介绍

1. 本质

如果我们把互联网比作一张大的蜘蛛网,那一台计算机上的数据便是蜘蛛网上的一个猎物,而爬虫程序就是一只小蜘蛛,沿着蜘蛛网抓取自己想要的猎物/数据

本质:模拟发送http请求(requests)----》解析返回数据(re,bs4,lxml,json)---》入库(redis,mysql,mongodb)

2. 爬虫价值

互联网中最有价值的便是数据,比如天猫商城的商品信息,链家网的租房信息,雪球网的证券投资信息等等,这些数据都代表了各个行业的真金白银,可以说,谁掌握了行业内的第一手数据,谁就成了整个行业的主宰,如果把整个互联网的数据比喻为一座宝藏,那我们的爬虫课程就是来教大家如何来高效地挖掘这些宝藏,掌握了爬虫技能,你就成了所有互联网信息公司幕后的老板,换言之,它们都在免费为你提供有价值的数据。

其实百度,谷歌,就是个大爬虫  在百度搜索,其实是去百度的服务器的库搜的,百度一直开着爬虫,一刻不停的在互联网上爬取,把页面存储到自己库中

可以爬取律师网站、房源信息、医疗、简历库,然后搭建一个搜索网站(APP,小程序)

3. 为什么Python做爬虫好

Python的包多,有爬虫的框架:scrapy,性能高,是爬虫界的Django所有爬虫相关的东西都集成了

4. 爬虫四部曲

#1、发起请求
使用http库向目标站点发起请求,即发送一个Request
Request包含:请求头、请求体等

#2、获取响应内容
如果服务器能正常响应,则会得到一个Response
Response包含:html,json,图片,视频等

#3、解析内容
解析html数据:正则表达式,第三方解析库如Beautifulsoup,pyquery等
解析json数据:json模块
解析二进制数据:以b的方式写入文件

#4、保存数据
数据库
文件

2. HTTP协议

1. 特点

1、基于TCP/IP 协议之上的应用层协议

mysql,redis,MongoDB:CS架构的软件:Navicat,pymysql都是mysql客户端 通过socket自己定制的协议连接到服务端

docker,es 都是通过http(resful规范)连接到服务端

2、一次请求一次响应

客户端主动发起请求,服务端才能响应

3、无状态保存(cookie,session,token)

session:只对当前域名下有效,只适用于客户端代码和服务端代码在同一个服务器上的,session服务器会保存一份,key:用户信息

token:前后端分离,域名可以不一样,再次请求需要认证信息,authorization=token:用户信息

4、无连接

发送一次完请求,响应完就断开

1.x:线程阻塞,在同一时间内,同一域名请求的数量是有限的,超过限制数就会阻塞

2.0:采用二进制格式高效错误更少,完全多路复用,非阻塞的一个连接可并行,使用报头压缩降低开销

1.x与2.x与https详细

2. 数据格式

  1. 请求格式

    • 请求首行(请求方式,url,协议版本)

    • 请求头(一大堆k, v 键值对)

      请求头包含许多有关的客户端环境和请求体的有用信息。例如,请求头可以声明浏览器所用的语言,请求体的长度等。
      Accept:image/gif.image/jpeg.*/*
      Accept-Language:zh-cn
      Connection:Keep-Alive
      Host:localhost
      User-Agent:Mozila/4.0(compatible:MSIE5.01:Windows NT5.0)
      Accept-Encoding:gzip,deflate.
    • 空行:表示请求头已经结束,接下来的是请求体

    • 请求体(携带的数据 并不是一直都有,有时候可能是空的,取决于你的请求方式)

  1. 响应格式

    • 响应首行(响应状态码)
    • 响应头(一大堆k, v 键值对)
      响应头(Response Header)响应头也和请求头一样包含许多有用的信息,例如服务器类型、日期时间、内容类型和长度等:
      Server:Apache Tomcat/5.0.12
      Date:Mon,6Oct2003 13:13:33 GMT
      Content-Type:text/html
      Last-Moified:Mon,6 Oct 2003 13:23:42 GMT
      Content-Length:112
    • 空行
    • 响应体(浏览器展示给用户看的数据)

3. requests模块

可以模拟发送http请求,Python内置有urlib2内置库不好用,有人就封装成了requests模块

需要下载:pip3 install requests

1. 基本使用

#各种请求方式:常用的就是requests.get()和requests.post()
>>> import requests
>>> r = requests.get('https://api.github.com/events')
>>> r = requests.post('http://httpbin.org/post', data = {'key':'value'})
>>> r = requests.put('http://httpbin.org/put', data = {'key':'value'})
>>> r = requests.delete('http://httpbin.org/delete')
>>> r = requests.head('http://httpbin.org/get')
>>> r = requests.options('http://httpbin.org/get')

2. get请求

import requests

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

3. get请求携带参数

# 方式一:直接在url中携带
ret = requests.get('https://www.baidu.com/name=‘sy’',
                   headers={
                        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'
                   }
                   )
print(ret.text)

# 方式二:params中携带(建议使用)中文会自动转码
ret = requests.get('http://127.0.0.1:8000/',
                    params={'name': "美女", 'age': 18}
                   )
print(ret.text)

# headers中携带User-Agent,Referer
 ret = requests.get('http://127.0.0.1:8000/', headers={ # 标志,什么东西发出的请求,浏览器信息,django框架,从(meta)中获取 'User-Agent': 'Windows NT 10.0; WOW64', # 上一个页面的地址,图片防盗链 'Referer': 'xxx' }, params={'name': "美女", 'age': 18} ) print(ret.text)

4. 携带cookie

## 方式1 headers中携带
ret = requests.get('https://www.cnblogs.com/Mr-shen/',
                   headers={
                        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36',
                        'cookie':'_ga=GA1.2.92651;yymWa9zVkZoKw'
                   })
print(ret.text)

## 方式2 cookies中携带
ret = requests.get('http://127.0.0.1:8000/?name=%E7%BE%8E%E5%A5%B3',
                   cookies={"islogin":"xxx"})
print(ret)

5. post请求

携带数据是在data中,可以使用json编码后发送

# 发送post请求(注册,登陆),携带数据(body)
#data=None, json=None
# data:urlencoded编码
ret=requests.post('http://0.0.0.0:8001/',data={'name':"lqz",'age':18})
# json:json编码,Django后台在body中获取
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) # 如果有重定向,放到一个列表中
# 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

ret = requests.get('http://127.0.0.1:8000/')
a = ret.json()
print(a)
print(type(a))

10. 使用代理

    正向代理是对客户端的代理,由客户端设立,客户端了解代理服务器和目标服务器,但目标服务器不了解真正的客户端是谁;使用正向代理可达到 突破访问限制、提高访问速度、对服务器隐藏客户端IP等目的;

    反向代理是对服务器的代理,由服务器设立,客户端不了解真正的服务器是谁,使用反向代理可达到负载均衡、保障服务端安全、对客户端隐藏服务器IP等目的。

requests是使用的正向代理

Django中获取客户端 ip

request.META.get('REMOTE_ADDR')

使用代理,别人获取不到我们客户端真正的ip地址只能获取到代理ip

如何使用:proxies={'http': '代理地址'}

# ret=requests.get('http://0.0.0.0:8001/',proxies={'http':'222.85.28.130:40505'})
# print(type(ret.text))
# print(ret.text)

代理地址网上会有免费的代理,但是不稳定

高匿:服务端,根本不知道我是谁
普通:服务端是能够知道我的ip的

使用代理有什么用:drf 1分钟只能访问6次,限制了ip,每次发请求都使用不同的代理就可以解决

4. 爬虫简单练习

1. 爬取梨视频

import requests
import re  # 正则模块
# uuid.uuid4()  可以根据时间戳生成一段世界上唯一的随机字符串
import uuid
# 导入线程池模块
from concurrent.futures import ThreadPoolExecutor
# 线程池限制50个线程
pool = ThreadPoolExecutor(50)

# 爬虫三部曲

# 1、发送请求
def get_page(url):
    print(f'开始异步任务: {url}')
    response = requests.get(url)
    return response


# 2、解析数据
# 解析主页获取视频详情页ID
def parse_index(res):

    response = res.result()
    # 提取出主页所有ID
    id_list = re.findall('<a href="video_(.*?)"', response.text, re.S)
    # print(res)

    # 循环id列表
    for m_id in id_list:
        # 拼接详情页url
        detail_url = 'https://www.pearvideo.com/video_' + m_id
        # print(detail_url)
        # 把详情页url提交给get_page函数
        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]
    # 异步提交把视频url传给get_page函数,把返回的结果传给save_movie
    pool.submit(get_page, movie_url).add_done_callback(save_movie)


# 3、保存数据
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()


if __name__ == '__main__':  # main + 回车键

    # 一 往get_page发送异步请求,把结果交给parse_index函数
    url = 'https://www.pearvideo.com/'
    pool.submit(get_page, url).add_done_callback(parse_index)

2. 自动登录网站

import requests

ret = requests.post('http://www.aa7a.cn/user.php',
                    # 登录页面登录时检查携带的哪些参数
                    data={
                        'username': '616564099@qq.com',
                        'password': 'lqz123',
                        'captcha': 'fszc',
                        'remember': '1',
                        'ref': 'http://www.aa7a.cn/',
                        'act': 'act_login',
                    }
                    )

cookie = ret.cookies.get_dict()
print(cookie)

# 获取到cookies后就可以正常使用了
ret1 = requests.get('http://www.aa7a.cn/', cookies=cookie)
print('616564099@qq.com' in ret1.text)

 

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


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

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

 

posted @ 2020-04-07 22:57  Mr沈  阅读(302)  评论(0编辑  收藏  举报