美文网首页
Requests-HTML模块

Requests-HTML模块

作者: 一个无趣的人W | 来源:发表于2019-08-13 19:30 被阅读0次

    Talk is cheap,Show me your code.

    官方文档:http://html.python-requests.org

    中文文档:https://cncert.github.io/requests-html-doc-cn/#/?id=rebuild_methodprepared_request-response

    GitHub:https://github.com/Liangchengdeye/Requests_Html_Spider

    一、简介

    1、编写爬虫时requests+BeautifulSoup是一对完美的组合,先通过requests模块将网页爬取下来,再交给BeautifulSoup等一些html解析库进行解析,而requests_html可以直接解析。

    2、优点

    • 支持JavaScript
    • 支持CSS选择器
    • 支持xpath选择器
    • 模拟用户代理
    • 自动重定向
    • 连接池和cookie持久性
    • 支持异步

    Tips:看文档说这个模块只支持py3.6,但这个库还在更新,所以py3.6及以上版本应该都能用。

    3、安装
    pip install requests-html

    二、使用

    1、请求网页

    from requests_html import HTMLSession
    session = HTMLSession()
    参数:
          browser.args = [
          '--no-sand',
          '--user-agent = XXXXX'
          ]
    
    比如:
    session = HTMLSession(
        browser_args=[
            '--no-sand',
            '--user-agent=计算机配置'
        ]  # , headless=False  # ⚠️去改源码
    )
    
    get请求参数:
        url 【请求的路由】
        headers = {}  【头部信息】 优先级高于cookie
        params = {}  【参数】
        proxies = {'http':'http://端口:ip'}  【代理IP】
        timeout = 0.5  【网页响应超时时间】
        allow_redirects = False  【是否允许重定向,默认True】
    
    post请求参数:
        url 【请求的路由】
        header = {}  【头部信息】
        cookies = {} 【header中有cookie信息,另外单独传入cookie】
        data = {}  【post请求数据是放在数据体中的】
        json = {}  【json格式的数据】
        files = {'file':open(...,'rb')} 【文件数据】
        timeout = 0.5  【网页响应超时时间】
        allow_redirects = False  【是否允许重定向,默认True】
    
    ⚠️源码改动3处
    (1)from requests_html import HTMLSession 进入
    (2)class HTMLSession(BaseSession):
            def __init__(self, **kwargs):
                super(HTMLSession, self).__init__(**kwargs)
    (3)因为继承的是BaseSession,所以进入BaseSession修改三处地方
    
    将头部写活 添加头部

    2、响应

    url = "要请求的网页链接"
    响应对象 = session.get(url=url)
    响应对象 = session.post(url=url)
    响应对象 = session.request(method='get/post',url=url)
    
        
    响应属性:
      响应对象.url 【获取url】
      响应对象.text  【获取响应文本】
      响应对象.encoding = 'GBK/UTF_8'  【设置网页编码】
      响应对象.content  【获取网页上的二进制图片、视频】
      响应对象.json()  【获取json格式数据】
      响应对象.status_code  【状态码】
      响应对象.headers  【获取头部信息】
      响应对象.cookies 【获取cookies信息】
      响应对象.history  【获取历史信息】
    

    3、解析
    这个库是解析HTML,所以解析的都是html对象

    (1) html对象属性(值):

      响应对象.html.absolute_links  【绝对路径,自动添加http://,自动补全和其他链接地址一样,返回的链接自动转为绝对路径】
      响应对象.html.links 【以列表形式提取、返回响应源码中的所有url链接】
      响应对象.html.base_url  【基础路径,就是主路径,一般是一个网站的网址】
      响应对象.html.html  【html网页】
      响应对象.html.text  【网页中的文本内容】
      响应对象.html.encoding  【获取编码方式】
      响应对象.html.encoding='GBK'  【输出的文本出现乱码,这时就需要指定编码方式,🍓在控制台输入document.charset查看编码类型】
      响应对象.html.raw_html  【未解析过的网页】
      响应对象.html.pq  【<class 'pyquery.pyquery.PyQuery'> pyquery对象】
    

    ✨🍰✨(2) html对象方法:

    • 响应对象.html.find () —— 使用css解析器
    r.html.find('css选择器')
    r.html.find('css选择器',first=True)
    
    r.html.find('#footer')  # 查找footer标签元素对象
    r.html.find('a',first=True)  # 查找第一个a标签元素对象
    

     🍋find函数有5个参数:
     selector【css解析式,要用的CSS选择器】
     first 【布尔值,如果为真则表示获取符合css表达式的第一个元素对象,否则返回满足条件的元素对象列表】
     containing【如果指定,则只返回包含提供文本的元素,放在列表中】
     clean【布尔值,是否消除 <script> 和<style> 标签对html产生的影响】
     _encoding【编码方式】

     🍋因为函数获得的是元素,所以元素还有他的属性

    ----- 响应对象.html.find().text ----
    r.html.find('a', first=True).text  >>> 获取元素的文本内容
    >>>输出:校花网
    
    ----- 响应对象.html.find().attrs ----
    r.html.find('a', first=True)  >>> 查找元素对象
    r.html.find('a', first=True).attrs)  >>>获取元素所有的属性
    r.html.find('a', first=True).attrs['href'] >>> 获取元素的具体属性,返回值是个字典
    
    >>>输出:
    >>>  <Element 'a' href='http://www.xiaohuar.com' title='校花网'>
    >>>  {'href': 'http://www.xiaohuar.com', 'title': '校花网'}
    >>>  http://www.xiaohuar.com
    
    ----- 响应对象.html.find().html ----
    r.html.find('a', first=True).html  >>> 查找html内容
    >>>输出 <a href="http://www.xiaohuar.com" title="&#x6821;&#x82B1;&#x7F51;">校花网</a>
    

    ⭕️CSS选择器:
      (1) 类名选择器
        class ——> .类名
      (2) id选择器
        id ——> #id名
      (3) 标签选择器
        p ——> 标签p
      (4) 后代选择器
        所有:儿子,孙子,重孙...
        ul li a
      (5) 子选择器
        只有儿子
        ul li
      (6) 属性选择器(5种)
        [属性] 用于选取带有指定属性的元素
        [属性=值] 用于选取带有指定属性和值的元素
        [属性^=值] 匹配属性值以指定值开头的每个元素
        [属性$=值] 匹配属性值以指定值结尾的每个元素
        [属性~=值] 用于选取属性值中包含指定词汇的元素
        [属性=*值] 匹配属性值中包含指定值的每个元素
      (7) 群组选择器
        选择器1,选择器2... 相当于or
      (8) 多条选择器
        选择器1选择器2... 相当于and

    更多用法:https://www.w3school.com.cn/cssref/css_selectors.asp


    • 响应对象.html.xpath() —— 使用path解析器
    r.html.xpath('xpath选择器')  
    r.html.xpath('xpath选择器',first=True)
    
    h.html.xpath("//div[@id='menu']/a")
    h.html.xpath("//div[@id='menu']",first=True  
    

    参数和属性参照css选择器。


    ⭕️XPath选择器
    语法:
    (1) 选取节点

    表达式 描述
    nodename 选取此节点的所有子节点
    / 从根节点选取
    // 从匹配选择的当前节点选择文档中的节点,而不考虑它们的位置
    . 选取当前节点
    .. 选取当前节点的父节点
    @ 选取属性

    实例🌰

    路径表达式 结果
    bookstore 选取 bookstore 元素的所有子节点
    /bookstore 选取根元素 bookstore。
    注释:假如路径起始于正斜杠( / ),则此路径始终代表到某元素的绝对路径!
    bookstore/book 选取属于 bookstore 的子元素的所有 book 元素
    //book 选取所有 book 子元素,而不管它们在文档中的位置
    bookstore//book 选择属于 bookstore 元素的后代的所有 book 元素,而不管它们位于 bookstore 之下的什么位置
    //@lang 选取名为 lang 的所有属性

    (2)谓语:用来查找某个特定的节点或者包含某个指定的值的节点
    实例🌰

    路径表达式 结果
    /bookstore/book[1] 选取属于 bookstore 子元素的第一个 book 元素
    /bookstore/book[last()] 选取属于 bookstore 子元素的最后一个 book 元素
    /bookstore/book[last()-1] 选取属于 bookstore 子元素的倒数第二个 book 元素
    /bookstore/book[position()<3] 选取最前面的两个属于 bookstore 元素的子元素的 book 元素
    //title[@lang] 选取所有拥有名为 lang 的属性的 title 元素
    //title[@lang='eng'] 选取所有 title 元素,且这些元素拥有值为 eng 的 lang 属性
    /bookstore/book[price>35.00] 选取 bookstore 元素的所有 book 元素,且其中的 price 元素的值须大于 35.00
    /bookstore/book[price>35.00]/title 选取 bookstore 元素中的 book 元素的所有 title 元素,且其中的 price 元素的值须大于 35.00

    (3) 选取未知节点

    通配符 描述
    * 匹配任何元素节点
    @* 匹配任何属性节点
    node() 匹配任何类型的节点

    实例🌰

    路径表达式 结果
    /bookstore/* 选取 bookstore 元素的所有子元素
    //* 选取文档中的所有元素
    //title[@*] 选取所有带有属性的 title 元素

    (4) 选取若干路径
    实例🌰:通过在路径表达式中使用“|”运算符,可以选取若干个路径

    路径表达式 结果
    //book/title 竖杠 //book/price 选取 book 元素的所有 title 和 price 元素
    //title 竖杠 //price 选取文档中的所有 title 和 price 元素
    /bookstore/book/title 竖杠 //price 选取属于 bookstore 元素的 book 元素的所有 title 元素,以及文档中所有的 price 元素

    更多用法:https://www.w3school.com.cn/xpath/index.asp


    • 响应对象.html.search() —— 搜索元素的文本内容
    r.html.search('模板')  # 查出一个
    r.html.search_all('模板')  # 查出所有
    
    🌰:r.html.search('我觉得很有{}理')[0]  >>>输出:道
        r.html.search('我觉得很{a}道{test}')['test']  >>>输出:理
    
    🐨tips:如果没有找到的话返回网页
    
    • 响应对象.html.render() —— JavaScript支持
      内置支持js渲染,对以往需要使用Selenium获取源码的页面可不再额外使用Selenium库操作。
      render方法将会渲染页面的JavaScript,返回渲染后的数据。
      特别注意的是:在初次使用该功能的时候会自动下载支持包:Chromium
    from requests_html import HTMLSession
    
    session = HTMLSession()
    r = session.get('http://python-requests.org/')
    r.html.render()
    

    🍋render()方法可用参数:
      retries 【在Chromium里加载页面的重试次数】
      script 【执行页面上的JavaScript (可选参数) 】
      wait 【页面加载前的等待时间,防止超时 (单位:秒,可选参数) 】
      scrolldown 【接收整数参数n,如果提供参数n,表示向后翻n页】
      sleep 【在页面初次渲染之后的等待时间】
      reload 【如果为False,则不会重新从浏览器加载内容,而是读取内存里的内容】
      keep_page 【如果为True,将会允许你通过r.html.page与浏览器页面交互】

    🐨Tips:如果scrolldown和sleep都指定,那么程序会在暂停相应时间后,再往后翻页面(如:scrolldown=10, sleep=1)

    scripy:"""( ) => {
    ​       js代码
    ​       js代码
    ​       }
    ​       """
    ​       scrolldow:n
    ​       sleep:n
    ​       keep_page:True/False
    
    ()=>{
    Object.defineProperties(navigator,{
            webdriver:{
            get: () => undefined
            }
        })
    

    🍋与浏览器交互
    (1) 页面事件 —— r.html.page.XXX

    ----- 格式 -----
    async def 函数名():  # 先定义一个函数
        await r.html.page.XXX  # 交互方式
    session.loop.run_until_complete(函数名())  # 调用
    
     ----- 交互方式 -----
    r.html.page.screenshot({"path":路径})  # 截屏
    r.html.page.evaluate("""()=>{js代码}""")  
    r.html.page.cookies()
    r.html.page.type('css选择器','内容',{'delay':100})
    r.html.page.click('css选择器')  # 点击
    r.html.page.focus('css选择器')  # 聚焦
    r.html.page.hover('css选择器')  # 悬浮
    r.html.page.waitForSelector('css选择器')
    r.html.page.waitFor(1000)  # 等待
    

    (2) 键盘事件 —— r.html.page.keyboard.XXX

    r.html.page.keyboard.type('咸鱼今天努力了没',{'delay':100})  # 键盘打字
    r.html.page.keyboard.up('Shift')  # Shift抬起,按键可以换成别的
    r.html.page.keyboard.down('Shift')  # Shift按下
    r.html.page.keyboard.press('ArrowLeft')  # 一直按左键进行选择
    

    (3) 鼠标事件 —— r.html.page.mouse.XXX

    r.html.page.mouse.click(x,y,{  # 点击
        'button':'left',
        'click':1
        'delay':0
    })
    r.html.page.mouse.down({'button':'left'})  # 鼠标按下
    r.html.page.mouse.up({'button':'left'}) # 鼠标抬起
    🐷一般up和down一起使用,表示点击一下
    r.html.page.mouse.movie(x,y,{'steps':1})  # 鼠标移动,步长为1表示移动一步就到,步长设置的越大,则步数越细,移动越慢
    

    练习:

    from requests_html import HTMLSession
    
    session = HTMLSession(
        browser_args=[
            '--no-sand',
            '--user-agent=自己的电脑配置'
        ]  # , headless=False  # ⚠️去改源码
    )
    
    url = 'http://www.google.com'
    # r = session.request(method='get', url=url)
    # print(dir(r.html.find('a',first=True)))
    #
    # a_element = r.html.find('#footer',first=True)
    # print(a_element.attrs['name'])
    # print(r.html.search_all('(提示:{name},最新章节可能会{pwd},登录书架即可实时查看。)')[0])
    
    r = session.request(method='get', url='https://www.bilibili.com/')
    
    scrapts = """
        ()=>{
            Object.defineProperties(navigator,{
            webdriver:{
            get:() => undefined
            }
        })}
    """
    
    try:
        r.html.render(script=scrapts, sleep=1, keep_page=True)
    
    
        async def main():
            await r.html.page.screenshot({"path": '1.png', 'clip': {'x': 200, 'y': 200, 'width': 400, 'height': 400}})
            res = await r.html.page.evaluate("""
            ()=>{
                var a = document.querySelector("#list")
                return {'x':a.offsetLeft}
            }
            """)
            print(res)
            print(await r.html.page.cookies())
            await r.html.page.type('#kw', '泷泽萝拉', {'delay': 500})
            await r.html.page.waitForSelector('[name="tj_trnews"]')
            await r.html.page.click('[name="tj_trnews"]')
            await r.html.page.focus('[type="number"]')
            await r.html.page.keyboard.type('111', {'delay': 200})
            await r.html.page.hover('[data-stat-id="6f5c93b4d1baf5e9"]')
            await r.html.page.keyboard.type('喜欢你啊', {'delay': 200})
            await r.html.page.keyboard.down('Shift')
            for i in range(3):
                await r.html.page.keyboard.press('ArrowLeft', {'delay': 1000})
            await r.html.page.keyboard.up('Shift')
            await r.html.page.keyboard.up('Backspace')
            res = await r.html.page.evaluate('''
            ()=>{
                car a = document.querySelector('[alt="【究极爆肝】德克萨斯与拉普兰德的感伤往事(明日方舟描改 动画手书·完整版)"]')
                return {
                    'x':a.x+a.width/2,
                    'y':a.y+a.height/2
                }
            }
            ''')
            print(res)
            await r.html.page.mouse.movie(res['x'], res['y'], {'step': 200})
            await r.html.page.mouse.down({'button': 'right'})
            await r.html.page.mouse.up({'button': 'right'})
            await r.html.page.mouse.click(res['x'], res['y'])
    
            await r.html.page.waitFor(5000)
        session.loop.run_until_complete(main())
    finally:
        session.close()
    

    实战:

    1、校花网图片
    # 对页码进行分析
    # http://www.xiaohuar.com/hua/
    # http://www.xiaohuar.com/list-1-1.html  第2页
    # http://www.xiaohuar.com/list-1-2.html  第3页
    
    import os
    from requests_html import HTMLSession
    
    # 生成所有页码url
    def get_page_url():
        for i in range(46):
            yield 'http://www.xiaohuar.com/list-1-{}.html'.format(i)
    
    session = HTMLSession()
    
    # 第一页解析测试
    url = "http://www.xiaohuar.com/list-1-0.html"
    
    # 解析页面,获取图片名和url
    def parse_page(url):
        r = session.request(method='get', url=url)
        img_element_list = r.html.find('[class="img"] img')
        for img_element in img_element_list:
            file_name1 = img_element.attrs.get('alt').replace('/', '').replace('\\', '')
            # print(file_name)
            file_name = file_name1 + '.png'
            file_url: str = img_element.attrs.get('src')
            file_url = r.html.base_url[:-1] + file_url if not file_url.startswith("http") else file_url
            save_file(file_name, file_url)
    
    # 保存图片
    def save_file(name, url):
        base_path = '校花图片'
        file_path = os.path.join(base_path, name)
        r = session.get(url=url)
        with open(file_path, 'wb') as f:
            f.write(r.content)
            print('%s下载成功' % name)
    
    
    if __name__ == '__main__':
        for page_url in get_page_url():
            parse_page(page_url)
    
    2、校花网视频
    """
    分析:校花网视频分为两种,一种是mp4格式的,一种是m3u8格式的,所以要分别进行处理
    """
    from requests_html import HTMLSession
    import os
    
    session = HTMLSession()
    
    # 获取索引页url
    def get_index_page():
        for i in range(6):
            url = 'http://www.xiaohuar.com/list-3-%s.html' % i
            yield url
    
    # 解析索引页获取详情页url
    # 解析详情页
    def get_detail_page(url):
        r = session.get(url=url)
        for element in r.html.find('#images a[class="imglink"]'):
            yield element.attrs.get('href')
    
    # 解析详情页获取视频url,名字
    # 获得名字,类型,链接
    def get_url_name(url):
        r = session.get(url=url)
        r.html.encoding = 'gbk'
        file_name = r.html.find("title", first=True).text.replace('\\', '')
        print(file_name)
        element = r.html.find('#media source', first=True)
        if element:
            vurl = element.attrs.get('src')
            vtype = 'mp4'
        else:
            vurl = r.html.search('var vHLSurl    = "{}";')[0]
            vtype = 'm3u8'
        return file_name, vurl, vtype
    
    
    # 保存文件
    def save(file_name, vurl, vtype):
        if vtype == "mp4":
            file_name += ".mp4"
            r = session.get(url=vurl)
            with open(file_name, 'wb') as f:
                f.write(r.content)
        elif vtype == "m3u8":
            save_m3u8(file_name, vurl)
    
    
    # 处理m3u8
    # save_m3u8('xxx','https://www6.laqddcc.com/hls/2019/05/05/BRsIeDpx/playlist.m3u8')
    def save_m3u8(file_name, vurl):
        if not os.path.exists(file_name):
            os.mkdir(file_name)
        r = session.get(url=vurl)
        m3u8_path = os.path.join(file_name, 'playlist.m3u8')
        with open(m3u8_path, 'wb') as f:
            f.write(r.content)
        for line in r.text:
            if line.endswith('ts'):
                ts_url = vurl.replace('playlist.m3u8', line)
                ts_path = os.path.join(file_name, line)
                r0 = session.get(url=ts_url)
                with open(ts_path, 'wb') as f:
                    f.write(r0.content)
    
    
    if __name__ == '__main__':
        for index_page in get_index_page():
            for detail_url in get_detail_page(index_page):
                file_name, vurl, vtype = get_url_name(detail_url)
                save(file_name, vurl, vtype)
    
    3、模拟知乎登录
    """
    分析:知乎用密码登录,总共发送3次请求,请求路由相同,但请求方式不同;验证码有两种方式,字母验证码和选择倒立文字验证码;两个加密,formdata加密和signature加密。
         3次请求:【第一次】https://www.zhihu.com/api/v3/oauth/captcha?lang=en  get请求检测是否需要验证码,传输的是json格式;
                 【第二次】https://www.zhihu.com/api/v3/oauth/captcha?lang=en  put获取验证码,返回的是base64格式的验证码;
                 【第三次】https://www.zhihu.com/api/v3/oauth/captcha?lang=en  post请求发送验证码。
         两种验证码:lang=en 英文;lang=cn 中文。
         signature加密是使用sha1和hmac;
         formdata加密是通过导入加密的js函数来反解出的。
    """
    import requests
    import base64
    import Image
    from time import sleep
    import hmac
    from hashlib import sha1
    import time
    from urllib.parse import urlencode
    import execjs
    import json
    
    
    class Zhihu(object):
        def __init__(self):
            self.session = requests.session()
            self.headers = {
                'referer': 'https://www.zhihu.com/signin?next=%2F',
                'user-agent': '自己的电脑配置'
            }
            self.picture = None  # 存验证码
            self.signature = None  # 存签名
            self.picture_url = None  # 存验证码链接
    
        def getbasecookie(self):
            self.session.get(url='https://www.zhihu.com/signin?next=%2F', headers=self.headers)
            self.session.get(url='https://www.zhihu.com/api/v4/search/preset_words', headers=self.headers)
            # self.session.post(url='https://www.zhihu.com/udid', headers=self.headers)  # 未知
    
        def getcapture(self):
            # 获取验证码方法,有时候不用获取验证码就可以直接登录
            # lang=en是英文字母,lang=cn是选倒过来的文字
            message = self.session.get(url='https://www.zhihu.com/api/v3/oauth/captcha?lang=en',
                                       headers=self.headers).json()  # get请求检测是否需要验证码,传输的是json格式
            print(message)  # {'show_captcha':True/False}
            if message['show_captcha'] == False:  # 如果不需要验证码
                self.picture = ''
            else:
                self.picture_url = self.session.put(url='https://www.zhihu.com/api/v3/oauth/captcha?lang=en',
                                                    headers=self.headers).json()  # put获取验证码,返回的是base64格式的验证码
                # 采用base64格式将验证码通过图片格式显示出来
                with open('captcha.jpg', 'wb') as f:
                    f.write(base64.b64decode(self.picture_url['img_base64']))
                image = Image.open('captcha.jpg')
                image.show()
                self.picture = input('请输入验证码:')
                sleep(2)
                message1 = self.session.post(url='https://www.zhihu.com/api/v3/oauth/captcha?lang=en',data={'input_text':self.picture},headers=self.headers).json()  # post请求发送验证码
                print(message1)
    
        def get_signature(self):
            # 知乎登录的主要问题在于找到signature,重点
            a = hmac.new('d1b964811afb40118a12068ff74a12f4'.encode('utf-8'),digestmod=sha1)
            a.update('password'.encode('utf-8'))
            a.update(b'c3cef7c66a1843f8b3a9e6a1e3160e20')
            a.update(b'com.zhihu.web')
            a.update(str(int(time.time()*1000)).encode('utf-8'))
            self.signature = a.hexdigest()
    
        def Login_phone(self):
            # 登录
            data = {
                'client_id': 'c3cef7c66a1843f8b3a9e6a1e3160e20',
                'grant_type': 'password',
                'timestamp': str(int(time.time() * 1000)),
                'source': 'com.zhihu.web',
                'signature': self.signature,
                'username': '+8615151979063',
                'password': '88404620wpr',
                'captcha': self.picture,
                'lang': 'en',
                'utm_source': '',
                'ref_source': 'other_https://www.zhihu.com/signin?next=%2F',
            }
    
            headers = {
                'scheme': 'https',
                'accept': '*/*',
                'accept-encoding': 'gzip, deflate, br',
                'accept-language': 'zh-CN,zh;q=0.8',
                'cache-control': 'no-cache',
                # 'content-length':'412',
                'pragma': 'no-cache',
                'origin': 'https://www.zhihu.com',
                'user-agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0',
                'content-type': 'application/x-www-form-urlencoded',
                'referer': 'https://www.zhihu.com/signin?next=%2F',
                'x-xsrftoken': self.session.cookies.get('_xsrf'),
                'x-requested-with': 'fetch',
                'x-ab-param': 'top_vipconsume=1;se_famous=1;se_featured=1;top_ebook=0;top_recall_exp_v1=1;se_topicdirect=2;li_ts_sample=old;qa_answerlist_ad=0;zr_ans_rec=gbrank;se_likebutton=0;se_d2q=0;top_root=0;pf_noti_entry_num=0;li_android_vip=0;se_limit=0;se_ltr_nn=0;se_time_threshold=0;top_gr_ab=0;pf_fuceng=1;ls_videoad=0;top_ydyq=X;qa_test=0;zr_art_rec=base;se_topiclabel=1;top_recall_exp_v2=1;ls_new_upload=0;zr_km_answer=open_cvr;se_webtimebox=0;se_backsearch=0;tp_meta_card=0;zr_search_xgb=0;zr_km_xgb_model=new_xgb;se_spb309=0;soc_special=0;li_album3_ab=0;li_se_xgb=0;se_p_slideshow=0;ls_fmp4=0;soc_bignew=1;soc_bigone=0;ug_zero_follow_0=0;zr_article_rec_rank=close;zr_km_paid_answer=0;se_ri=0;tp_sft_v2=d;zr_rec_answer_cp=close;se_agency= 0;tsp_hotctr=1;soc_notification=0;pf_foltopic_usernum=50;zr_video_rank=new_rank;se_whitelist=0;tp_sft=a;tp_header_style=1;ug_zero_follow=0;li_se_paid_answer=0;se_go_ztext=0;tp_topic_head=1;top_reason=1;li_qa_new_cover=0;se_expired_ob=0;top_recall_deep_user=1;tsp_lastread=0;li_qa_cover=old;li_price_test=1;tp_qa_metacard_top=top;se_rr=0;se_wannasearch=0;se_subtext=0;pf_creator_card=1;zr_km_tag=open;se_mclick1=0;se_movietab=1;top_v_album=1;ug_newtag=0;zr_km_slot_style=event_card;se_page_limit_20=1;se_zu_recommend=0;top_rank=0;zr_intervene=0;se_billboardsearch=0;se_new_topic=0;se_payconsult=0;soc_update=1;pf_feed=1;zr_answer_rec_cp=open;se_ltr_ck=0;tp_qa_metacard=1;top_universalebook=1;se_websearch=3;ug_goodcomment_0=1;ug_follow_answerer=0;zr_infinity_small=256;se_mclick=0;top_native_answer=1;li_hot_score_ab=0;zr_rel_search=base;zr_video_recall=current_recall;se_ad_index=10;se_college_cm=0;ug_fw_answ_aut_1=0;zr_video_rank_nn=new_rank;se_college=default;se_search_feed=N;ug_follow_topic_1=2;li_back=0;se_webrs=1;se_amovietab=1;top_new_feed=5;li_pay_banner_type=0;li_ebook_detail=1;se_preset_tech=0;se_colorfultab=1;tp_sticky_android=0;li_tjys_ec_ab=0;ug_follow_answerer_0=0;li_album_liutongab=0;li_se_kv=0;se_mobileweb=1;top_quality=0;se_lottery=0;top_test_4_liguangyi=1;zr_km_style=base;se_ios_spb309=0;se_auto_syn=0;tsp_vote=1;pf_newguide_vertical=0;tsp_childbillboard=1;li_se_album_card=0;se_ltr_gc=0;tp_qa_toast=1;tp_m_intro_re_topic=1;se_waterfall=0;top_hotcommerce=1;zr_infinity_a_u=close;se_webmajorob=0;se_zu_onebox=0;se_site_onebox=0',
                'x-zse-83': '3_2.0',
            }
            print(self.session.cookies.get('_xsrf'))
            print(urlencode(data))
    
            with open('知乎加密js.js','r',encoding='utf-8') as f:
                js = execjs.compile(f.read())  # 传入unicode字符
                data = js.call(u'b',urlencode(data))  # data_dict为表单数据
                print(data)
            message = self.session.post(url='https://www.zhihu.com/api/v3/oauth/sign_in',headers=headers,data=data)
            message.encoding='utf-8'
            print(message.text)
            print(json.loads(message.text)['error']['message'])
    
        def target_url(self,url):
            text = self.session.get(url)
            return text.text
    
    
    if __name__ == '__main__':
        zhihu = Zhihu()
        zhihu.getbasecookie()  # 首次cookie
        zhihu.getcapture()  # 验证码
        zhihu.get_signature()  # signature
        zhihu.Login_phone()  # 登录
    

    相关文章

      网友评论

          本文标题:Requests-HTML模块

          本文链接:https://www.haomeiwen.com/subject/ploqjctx.html