zoukankan      html  css  js  c++  java
  • requests高级

    requests高级

    • 自己完成的任务
      • pyquery
        • 标签定位和数据的提取
      • urllib
        • 如何进行请求的发送

    requests模块高级

    • 代理

    • 模拟登陆

      • 验证码
      • cookie
    • 代理(反爬机制)

      • 概念:代理服务器
      • 代理服务器的作用:
        • 拦截请求和响应,进行转发
      • 代理和爬虫之间的关联是什么?
        • 如果pc端的ip被禁掉后,我们就可以使用代理的机制更换请求的ip
      • 如何获取相关的代理服务器:
      • 匿名度:
        • 透明:知道你使用了代理也知道你的真实ip
        • 匿名:对方服务器知道你使用了代理机制,但是不知道你的真实ip
        • 高匿:对方服务器不知道你使用了代理机制更不知道你的真实ip
      • 类型:
        • http:只可以拦截转发http协议的请求
        • https:只可以转发拦截https的请求
    • 基本测试:代理的作用

      • 基于百度搜索ip,搜索到的页面中会显示该请求对应的ip地址
      • 语法结构
        • get/post(proxies={'http/https':'ip:port'})

    In [2]:

    import requests
    from lxml import etree
    headers = {
        'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.88 Safari/537.36'
    }
    

    In [34]:

    url = 'https://www.sogou.com/web?query=ip&_asf=www.sogou.com&_ast=&w=01019900&p=40040100&ie=utf8&from=index-nologin&s_from=index&sut=623&sst0=1578274254338&lkt=2%2C1578274253715%2C1578274253785&sugsuv=000AE8ACDDDAD0EB5DE49630C6588161&sugtime=1578274254338'
    #代理机制对应的就是get或者post方法中的一个叫做proxies的参数
    page_text = requests.get(url=url,headers=headers,proxies={'https':'14.134.184.156:39347'}).text
    print(page_text)
    

    . . .

    • 构建一个代理池

    In [27]:

    import random
    

    In [37]:

    #构建了一个代理池
    all_ips = []
    url = 'http://t.11jsq.com/index.php/api/entry?method=proxyServer.generate_api_url&packid=1&fa=0&fetch_key=&groupid=0&qty=21&time=1&pro=&city=&port=1&format=html&ss=5&css=&dt=1&specialTxt=3&specialJson=&usertype=2'
    page_text = requests.get(url=url,headers=headers).text
    tree = etree.HTML(page_text)
    datas = tree.xpath('//body//text()')
    for data in datas:
        dic = {
            'https':data
        }
        all_ips.append(dic)
    all_ips[0]
    

    Out[37]:

    {'https': '223.242.175.67:26524'}
    

    In [38]:

    #将西祠代理中的免费代理ip进行爬取
    url = 'https://www.xicidaili.com/nn/%d'#定义了一个通用的url模板
    datas = [] #存储解析到的所有的数据
    for pageNum in range(1,16):
        new_url = format(url%pageNum)
        page_text = requests.get(url=new_url,headers=headers,proxies=random.choice(all_ips)).text
        tree = etree.HTML(page_text)
        tr_list = tree.xpath('//*[@id="ip_list"]//tr')[1:]
        for tr in tr_list:#局部数据解析
            ip = tr.xpath('./td[2]/text()')[0]
            port = tr.xpath('./td[3]/text()')[0]
            dic = {
                'https':ip+':'+port
            }#{'https':'ip:port'}
            datas.append(dic)
    print(len(datas))
    1500
    

    模拟登陆

    • 为什么需要实现模拟登陆

      • 相关的页面是必须经过登陆之后才可现
    • 验证码的处理

      • 使用相关的打码平台进行验证码的动态识别

      • 打码平台:

      • 超级鹰的使用流程:

        • 注册【用户中心】身份的账号
        • 登陆
          • 创建一个软件
          • 下载示例代码
    • cookie的处理

    In [39]:

    #下载好的示例代码
    #!/usr/bin/env python
    # coding:utf-8
    
    import requests
    from hashlib import md5
    
    class Chaojiying_Client(object):
    
        def __init__(self, username, password, soft_id):
            self.username = username
            password =  password.encode('utf8')
            self.password = md5(password).hexdigest()
            self.soft_id = soft_id
            self.base_params = {
                'user': self.username,
                'pass2': self.password,
                'softid': self.soft_id,
            }
            self.headers = {
                'Connection': 'Keep-Alive',
                'User-Agent': 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0)',
            }
    
        def PostPic(self, im, codetype):
            """
            im: 图片字节
            codetype: 题目类型 参考 http://www.chaojiying.com/price.html
            """
            params = {
                'codetype': codetype,
            }
            params.update(self.base_params)
            files = {'userfile': ('ccc.jpg', im)}
            r = requests.post('http://upload.chaojiying.net/Upload/Processing.php', data=params, files=files, headers=self.headers)
            return r.json()
    
        def ReportError(self, im_id):
            """
            im_id:报错题目的图片ID
            """
            params = {
                'id': im_id,
            }
            params.update(self.base_params)
            r = requests.post('http://upload.chaojiying.net/Upload/ReportError.php', data=params, headers=self.headers)
            return r.json()
    
    
    # if __name__ == '__main__':
    #   chaojiying = Chaojiying_Client('超级鹰用户名', '超级鹰用户名的密码', '96001')  #用户中心>>软件ID 生成一个替换 96001
    #   im = open('a.jpg', 'rb').read()                                                 #本地图片文件路径 来替换 a.jpg 有时WIN系统须要//
    #   print chaojiying.PostPic(im, 1902)                                              #1902 验证码类型  官方网站>>价格体系 3.4+版 print 后要加()
    
    
    

    In [42]:

    #自己封装一个识别验证码的函数
    def transformCode(imgPath,imgType):
        chaojiying = Chaojiying_Client('bobo328410948', 'bobo328410948', '899370')
        im = open(imgPath, 'rb').read()
        return chaojiying.PostPic(im,imgType)['pic_str']
    
    • cookie的处理
      • 手动处理
        • 将请求携带的cookie封装到headers中
      • 自动处理
        • session对象。该对象和requests都可以进行get和post的请求的发送。如果使用session对象在进行请求发送过程中,产生了cookie,则cookie会被自动存储到session对象中。如果cookie存储到了session对象中后,再次使用session进行请求发送,则该次请求就是携带者cookie发送的请求。
        • 在使用session处理cookie的时候,session对象最少需要发送几次请求?
          • 两次。第一次请求是为了获取和存储cookie,第二次请求才是携带cookie进行的请求发送。

    In [51]:

    #需求:爬取雪球网https://xueqiu.com/,中的新闻标题和内容
    #实例化一个session对象
    session = requests.Session()
    #试图将cookie获取且存储到session对象中
    session.get('https://xueqiu.com/',headers=headers)
    url = 'https://xueqiu.com/v4/statuses/public_timeline_by_category.json?since_id=-1&max_id=20361817&count=15&category=-1'
    session.get(url=url,headers=headers).json()#携带cookie进行的请求发送
    
    

    . . .

    In [54]:

    session = requests.Session()
    
    
    #验证码的识别
    first_url = 'https://so.gushiwen.org/user/login.aspx?from=http://so.gushiwen.org/user/collect.aspx'
    page_text = session.get(first_url,headers=headers).text
    #解析出验证码图片的src的属性值
    tree = etree.HTML(page_text)
    code_img_src = 'https://so.gushiwen.org'+tree.xpath('//*[@id="imgCode"]/@src')[0]
    #对验证码图片地址进行请求发送
    code_img_data = session.get(code_img_src,headers=headers).content#产生了cookie
    with open('./code.jpg','wb') as fp:
        fp.write(code_img_data)
    
    
    #使用基于超级鹰实现的函数进行验证码的识别
    code_img_text = transformCode('./code.jpg',1902)
    print(code_img_text)
    
    url = 'https://so.gushiwen.org/user/login.aspx?from=http%3a%2f%2fso.gushiwen.org%2fuser%2fcollect.aspx'
    data = {
        '__VIEWSTATE': 'WQlcl775IHe1sjsai6HoahnPHU79MSS7ZyjzWaONdzwJSlR76Ndfm9mikHQVMTSwHZKIQ+fC8SeVGIU6b5AIb1spoHSnuoINERq+PdbI7vv/3+qaXK10HtmIw7w=',
        '__VIEWSTATEGENERATOR': 'C93BE1AE',
        'from': 'http://so.gushiwen.org/user/collect.aspx',
        'email': 'www.zhangbowudi@qq.com',
        'pwd': 'bobo328410948',
        'code': code_img_text,
        'denglu': '登录',
    }
    #点击登陆按钮对应的请求发送操作
    page_text = session.post(url=url,headers=headers,data=data).text
    with open('./gushiwen.html','w',encoding='utf-8') as fp:
        fp.write(page_text)
    78mx
    
    
    • 遇到了动态变化的请求参数如何处理?

      • 通常情况下,动态变化的请求参数的值都会被隐藏在前台页面中
      • 基于抓包工具进行全局搜索(基于js逆向获取相关的数据值)
    • 回顾

      • 代理
        • 概念
        • 作用
          • 请求转发
        • 实现:
          • get/post(proxies={'https':'ip:port'})
        • 代理池:大列表
          • 验证码的识别
          • 打码平台
          • cookie
          • 手动处理
          • 自动处理:session
          • 动态变化的请求参数
          • 前台页面
          • 全局搜索
    • 总结反爬机制:

      • robots
      • UA检测
      • 动态加载数据的捕获
      • 代理
      • 验证码
      • 动态变化的请求参数
      • cookie
      • 图片懒加载
        • 伪属性
    • 需求:爬取文本数据将其通过百度ai的语音合成功能将文字合成成音频文件,将将音频文件部署到flask服务器中进行播放

    In [58]:

    from aip import AipSpeech
    
    """ 你的 APPID AK SK """
    APP_ID = '17272609'
    API_KEY = 'h3Grp2xXGG0VeSAKlDL9gc4Q'
    SECRET_KEY = 'WEEeDpICnzifwBAGF4QW4QiGgSb1u3ND'
    client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
    
    #文本数据的爬取
    url = 'http://duanziwang.com/category/%E4%B8%80%E5%8F%A5%E8%AF%9D%E6%AE%B5%E5%AD%90/2/'
    page_text = requests.get(url,headers=headers).text
    
    tree = etree.HTML(page_text)
    article_list = tree.xpath('/html/body/section/div/div/main/article')
    fileName = 1
    for article in article_list:
        fileName += 1
        content = article.xpath('./div[1]/h1/a/text()')[0]
        #数据爬取到了,基于语音合成将其转换成音频文件
        result  = client.synthesis(content, 'zh', 1, {
        'vol': 5,
        'per':4,
        'spd':3,
    })
        # 识别正确返回语音二进制 错误则返回dict 参照下面错误码
        if not isinstance(result, dict):
            filePath = str(fileName)+'.mp3'
            with open(filePath, 'wb') as f:
                f.write(result)
            print(filePath,'写入成功!!!')
    2.mp3 写入成功!!!
    3.mp3 写入成功!!!
    4.mp3 写入成功!!!
    5.mp3 写入成功!!!
    6.mp3 写入成功!!!
    7.mp3 写入成功!!!
    8.mp3 写入成功!!!
    9.mp3 写入成功!!!
    10.mp3 写入成功!!!
    11.mp3 写入成功!!!
    
    python
  • 相关阅读:
    thrift java first demo
    找工作的一些感悟——前端小菜的成长
    常见标签的默认属性值及相互作用——关于CSS reset的思考
    CSS清浮动处理(Clear与BFC)
    简单JavaScript模版引擎优化
    最简单的JavaScript模板引擎
    JavaScript正则表达式下——相关方法
    JavaScript 正则表达式上——基本语法
    node.js调试
    node.js module初步理解
  • 原文地址:https://www.cnblogs.com/bky20061005/p/12157598.html
Copyright © 2011-2022 走看看