Advertisement

爬虫系统学习2——爬虫requests库

阅读量:

目录

  • 1、发送带headers的请求——模仿浏览器获取和浏览器一致的数据

    • (1)什么是参数
      • 注意:
  • 2、练习——贴吧爬虫

    • (1)回忆面向对象
    • (2)回忆快速生成列表
    • (3)代码及运行结果
  • 3、requests模块发送post请求

    • (1)回忆哪些地方会用到 POST 请求
    • (2)用法
    • (3)通过百度翻译的例子来看 post 请求如何使用
      • 代码
      • 结果
      • 自定义输入
  • 4、requests模块使用代理

    • (1)为什么爬虫需要使用代理?
    • (2)区别
    • (3)用法:
    • (4)分类
    • (5)代码
    • (6)注意
  • 5、requests模拟登录的三种方式

    • (1)cookie和session的区别

    • (2)爬虫处理 cookie 和 session

    • (3)处理 cookies session 请求

    • (4)使用session来登录easy-mock(仅需账号密码就能登录而不需要拖动进度条或者图形验证码的网站)

      • 使用 cookie 来登录easy-mock
    • (5)不发送 post 请求,直接使用 cookie 获取登陆后的网站

    • (6)cookie 作为 requests.get(cookies=) 的参数是字典——将字符串转化为字典 字典推导式

    • (7)总结:获取登录后页面的三种方式

  • 6、requests模块发送请求和获取网页字符串

    • 1) requests 中解决编解码问题
    • 2)response.content 和 response.text 的对比
  • 7、requests 保存图片——二进制文件的保存

引入:

复制代码
    # 判断状态码
    assert response.status_code==200 
    # 一些命令
    response=requests.get(url,headers=headers)
    response.headers
    response.request.url
    response.url
    response.request.headers
    
    
      
      
      
      
      
      
      
      
    
在这里插入图片描述

1、发送带headers的请求——模仿浏览器获取和浏览器一致的数据

(1)什么是参数

在这里插入图片描述

eg http://www.baidu.com/s?wd=python&c=d
参数的形式:字典
kw={‘wd’:‘长城’}
用法 requesr.get(url,params=kw)

复制代码
    import requests
    
    headers={'User-Agent':'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Mobile Safari/537.36'}
    p={'wd':'python'}
    
    r = requests.get('http://www.baidu.com/s?',headers=headers,params=p)
    print(r.status_code)
    print(r.request.url)
    
    
    
      
      
      
      
      
      
      
      
      
    
在这里插入图片描述

注意:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、练习——贴吧爬虫

(1)回忆面向对象

在这里插入图片描述

(2)回忆快速生成列表

复制代码
    [i for i in range(3)]
    [i+3 for i in range(3)]
    
    
      
      
    
在这里插入图片描述

(3)代码及运行结果

对比以下两端代码,应用面向对象思想的代码明显可读性要高很多

复制代码
    import requests
    class TiebaSpider:
    def __init__(self,tiebaname):#初始化
        self.tiebaname=tiebaname
        self.url_temp='http://tieba.baidu.com/f?kw='+tiebaname+'&ie=utf-8&pn={}'
        self.headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'}
    def run(self):#主程序执行
        # 1、制造 url 列表
        url_list=[self.url_temp.format(i*50) for i in range(50)]
        # 2、遍历、发送请求、获取响应
        for url in url_list:
            print(url)
            r = requests.get(url,headers=self.headers)
            c = r.content.decode()
            # 3、保存
            filepath = '{}-第{}页'.format(self.tiebaname,url_list.index(url)+1)# 李毅-第1页......
            with open(filepath,'w',encoding='utf-8') as f:
                f.write(c)
    
    if __name__=='__main__':
    tieba = TiebaSpider('李毅')
    tieba.run()
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    
复制代码
    import requests
    
    class TiebaSpider:
    def __init__(self,tiebaname):
        self.tiebaname=tiebaname
        self.headers={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'}
        self.url_temp='http://tieba.baidu.com/f?kw='+tiebaname+'&ie=utf-8&pn={}'
    
    def get_url_list(self):# 构造 Url 列表
        return [self.url_temp.format(50*i) for i in range(10)]
    
    def parse_url(self,url):# 发起请求,返回响应
        r = requests.get(url,headers=self.headers)
        return r.content.decode()
    
    def save(self,html_str,page_num):
        filepath='{}吧-第{}页.html'.format(self.tiebaname,page_num)# lol吧-第1页。html
        with open(filepath,"w",encoding='utf-8') as f:
            f.write(html_str)
    
    def run(self):
        # 1、构造 Url 列表
        url_lists=self.get_url_list()
        # 2、遍历、发起请求、获得响应
        for url in url_lists:
            html_str = self.parse_url(url)
            # 3、保存
            page_num = url_lists.index(url)+1
            self.save(html_str,page_num)
    
    if __name__=='__main__':
    tieba = TiebaSpider('lol')
    tieba.run()
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

这里仅展示部分:
在这里插入图片描述
在这里插入图片描述
爬取的html中有大量被注释掉的部分——原因:网页的源代码也被注释掉了在这里插入图片描述
为什么源代码被注释掉,在原网页依然正常显示:利用js将注释符号去掉

列表推导式
[self.url_temp.format(50*i) for i in range(10)]

3、requests模块发送post请求

requests 深入
发送 post 请求
使用代理
处理 cookies session

(1)回忆哪些地方会用到 POST 请求

  • 登陆注册
  • 需要传输大文本

(2)用法

复制代码
    r = requests.post('url',data=data,headers=headers)
    
    
      
    

data的形式:字典

(3)通过百度翻译的例子来看 post 请求如何使用

参考文档:链接: 百度翻译开发者文档
1
在这里插入图片描述
2
在这里插入图片描述
3
在这里插入图片描述

  • 使用 pycharm 小技巧——重新格式化代码来美化代码,提高代码的可读性
    在这里插入图片描述
  • 使用 pycharm 小技巧 光标跳到行首或者行尾快捷键:
    Ctrl + 左方括号 快速跳到代码开头
    Ctrl + 右方括号 快速跳到代码末尾

代码

复制代码
    # -*- coding: utf-8 -*-
    
    # This code shows an example of text translation from English to Simplified-Chinese.
    # This code runs on Python 2.7.x and Python 3.x.
    # You may install `requests` to run this code: pip install requests
    # Please refer to `https://api.fanyi.baidu.com/doc/21` for complete api document
    
    import requests
    import random
    import json
    from hashlib import md5
    
    # Set your own appid/appkey.
    appid = '20240604002069765'
    appkey = 'FYj6ztBmjGCjXlfQ8FdM'
    
    
    from_lang = 'auto'
    to_lang =  'zh'
    
    endpoint = 'http://api.fanyi.baidu.com'
    path = '/api/trans/vip/translate'
    url = endpoint + path
    
    query = 'Hello World! This is 1st paragraph.\nThis is 2nd paragraph.'
    
    # Generate salt and sign-----salt:随机数	可为字母或数字的字符串--------sign:签名	appid+q+salt+密钥的MD5值
    def make_md5(s, encoding='utf-8'):
    return md5(s.encode(encoding)).hexdigest()
    
    salt = random.randint(32768, 65536)
    sign = make_md5(appid + query + str(salt) + appkey)
    
    # Build request
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    payload = {'appid': appid, 'q': query, 'from': from_lang, 'to': to_lang, 'salt': salt, 'sign': sign}
    
    # Send request
    r = requests.post(url, params=payload, headers=headers)
    result = r.json()
    
    # Show response
    print(json.dumps(result, indent=4, ensure_ascii=False))
    
    #json.dumps():这是 Python json 模块中的一个函数,用于将 Python 对象(通常是字典或列表)转换为 JSON 格式的字符串
    
    res=[i['dst'] for i in result["trans_result"]]
    print(res)
    
    
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
      
    

结果

在这里插入图片描述
在这里插入图片描述

自定义输入

query=input()
from_lang = ‘auto’
to_lang = ‘en’
在这里插入图片描述

4、requests模块使用代理

(1)为什么爬虫需要使用代理?

  • 让服务器以为不是同一个客户端在请求
  • 防止我们的真实地址被泄露,防止被追究

(2)区别

浏览器知道服务器的信息:正向代理(vpn访问google服务器)
不知道服务器的信息:反向代理(django nginx)
在这里插入图片描述

(3)用法:

复制代码
    requests.get("http://www.baidu.com", proxies = proxies)
    #proxies的形式:字典
    
    
      
      
    

(4)分类

透明、高匿、普匿

(5)代码

复制代码
    # https://www.kuaidaili.com/free/intr
    import requests
    proxies={'http':'http://8.220.204.215:8008'}
    headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'}
    r = requests.get('http://www.baidu.com',proxies=proxies,headers=headers)
    print(r.status_code) #200
    
    
      
      
      
      
      
      
    

(6)注意

  • 准备一堆ip地址,组成ip池,随机选择一个ip来使用

  • 如何随机选择代理ip,让使用次数较少的Ip地址有更大的可能性被用到
    (1){“ip”:ip,“times” :0}
    (2)[{},{},{},{},{}}],对这个ip的列表进行排序,按照使用次数进行排序
    (3)选择使用次数较少的10个ip,从中随机选择一

  • 检查ip的可用性
    (1)可以使用requests添加超时参数,判断ip地址的质量
    (2)在线代理ip质量检测的网站

5、requests模拟登录的三种方式

(1)cookie和session的区别

  • cookie数据存放在客户的浏览器上,session数据放在服务器上
  • cookie不是很安全,别人可以分析存放在本地的cookie并进行cookie欺骗。
  • session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能
  • 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。
  • 带上cookie、session的好处
    能够请求到登录之后的页面

  • 带上cookie、session的弊端
    一套cookie和session往往和一个用户对应请求太快,请求次数太多,容易被服务器识别为爬虫

  • 不需要cookie的时候尽量不去使用cookie
    但是为了获取登录之后的页面,我们必须发送带有cookies的请求

(3)处理 cookies session 请求

requests 提供了一个叫做session类,来实现客户端和服务端的会话保持
使用方法:
1.实例化一个session对象
2让session发送get或者post请求
session=requests.session()
response=session.get(url,headers

使用requests提供的session类来请求登录之后的网站的思路:

  • 实例化session
  • 先使用session发送请求,登录网站,把cookie保存在session中
  • 再使用session请求登陆之后才能访问的网站,session能够自动的携带登录成功时保存在其中的cookie,进行请求

(4)使用session来登录easy-mock(仅需账号密码就能登录而不需要拖动进度条或者图形验证码的网站)

复制代码
    import requests
    s = requests.session()
    post_url='https://mock.presstime.cn/login'
    post_data={'name':'damon','password':'wy062600'}
    headers={'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36'}
    # 使用session发送post请求,cookie保存在其中
    s.post(post_url,data=post_data,headers=headers)
    #在使用session进行请求登录后才能访问的地址
    r=s.get('https://mock.presstime.cn/',headers=headers)
    #保存页面
    with open('1.html','w',encoding='utf-8') as f:
    f.write(r.content.decode())
    
    
      
      
      
      
      
      
      
      
      
      
      
      
    

说明:post_data查看方式:
在这里插入图片描述
代码运行结果:保存文件结果和个人主页源代码一致
在这里插入图片描述
在这里插入图片描述

复制代码
    import requests
    # 将 cookie 放在 headers 中
    headers={
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36',
    'cookie':'easy-mock_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjY3NDllNDRkODNlZTAxMTEzMmJjMjQzYyIsImlhdCI6MTczMjg5NTgyMSwiZXhwIjoxNzM0MTA1NDIxfQ.WaO8C8Hl2bQ1ISSQFqiVBu-C0T1k1vNI_b_qigBJ-6o',
    }
    # 利用requests.get 获取主页内容
    r=requests.get('https://mock.presstime.cn/',headers=headers)
    #保存页面
    with open('2.html','w',encoding='utf-8') as f:
    f.write(r.content.decode())
    
    
      
      
      
      
      
      
      
      
      
      
      
    

运行结果同上
在这里插入图片描述

  • 直接带 cookie 可以使得代码更简洁

(5)不发送 post 请求,直接使用 cookie 获取登陆后的网站

  • cookie 过期时间很长的网站
  • 在 cookie 过期之前能够拿到所有的数据 比较麻烦
  • 配合其他工具一起使用,其他程序专门获取 cookie ,当前程序专门请求页面

(6)cookie 作为 requests.get(cookies=) 的参数是字典——将字符串转化为字典 字典推导式

复制代码
    cookies='a=1; b=2; c=3'
    cookies={i.split('=')[0]:i.split('=')[1] for i in cookies.split('; ')}
    print(cookies)
    
    
      
      
      
    
在这里插入图片描述

(7)总结:获取登录后页面的三种方式

  • 实例化session,使用session发送post请求,再使用他获取登陆后的页面
  • headers中添加cookie键,值为cookie字符串
  • 在请求方法中添加cookies参数,接收字典形式的cookie。字典形式的cookie中的键是cookie的name对应的值,值是cookie的value对应的值

6、requests模块发送请求和获取网页字符串

复制代码
    import requests
    
    r = requests.get('http://www.baidu.com')
    print(r.status_code)
    print(r.encoding) # utf-8
    print(r.text) # response属性一般是名词,方法一般是动词
    print(r.content) # bytes类型通过decode()进行解码
    print(r.content.decode()) # 默认 utf-8 进行解码
    
    
      
      
      
      
      
      
      
      
    

1) requests 中解决编解码问题

复制代码
    response.content.decode()  # 推荐
    response.content.decode('gbk')
    response.text
    
    
      
      
      
    

2)response.content 和 response.text 的对比

response.text

  • 类型:str
  • 解码类型:根据HTTP 头部对响应的编码作出有根据的推测,推测的文本编码
  • 如何修改编码方式:response.encoding=‘gbk’

response.content

  • 类型:bytes
  • 解码类型: 没有指定
  • 如何修改编码方式:response.content.deocde(“utf8”)

推荐 response.content.decode() : 因为用 response.text 修改编解码要些两行代码

7、requests 保存图片——二进制文件的保存

复制代码
    import requests
    
    r = requests.get('https://requests.readthedocs.io/en/latest/_static/requests-sidebar.png')
    
    with open('a.png','wb') as f:
    f.write(r.content)
    
    
      
      
      
      
      
      
    
  • 保存方式是 wb 的原因:wb 表示以 bytes 二进制类型保存,而 w 表示以 str 字符串的类型保存,图片(视频等二进制文件)只有以二进制的方式保存才能显示出来
    • r.content 是二进制内容
      在这里插入图片描述

全部评论 (0)

还没有任何评论哟~