zoukankan      html  css  js  c++  java
  • requestium

    chrome浏览器的安装版或绿色便携版要加.exe,chromedriver驱动无.exe。
    不显示……测试软件的控制、无头同在[]内,插件等新版,无图用{};CentBrowser的Chrome内核版本低,暂用不了headless。
     
    from requestium import Session,Keys
     
    options={'arguments':['disable-infobars','headless'],  #'extensions':['D:/去广告 3.2.crx']
        'experimental_options':{'prefs':{'profile.managed_default_content_settings.images':2}},
        'binary_location': 'D:/Program Files/Browser/ChromeQuic/chrome.exe'}
    s=Session('C:/Program Files/Python36/chromedriver','chrome',7,options)
     
    #s.proxies.update({'http':f'http://{ip:port}','https':f'https://{ip:port}'})  #s.headers={'User-Agent':'…'}
    #s.driver.get('about:blank')
    *******************分割线*******************
    提取或定位:
     
    s.driver、s.get('',headers={}).json()、s.post('',data={}).content.decode(),这仨请求都有3.5个返回普通对象的提取法——任意匹配为((.|s)*?)的re_first和re,需.extract()的css和xpath,前者返回str,后仨是list:
    .re_first('d+',default='555')、.re('')[0]、.xpath('').extract()[0]、.css('').extract_first(default='666')
     
    re.findall(pattern,string,re.S)提取外()和内()的值用的是双层索引,即[num][0]和[num][1],而requestium中的re却有点特殊,外&内()的值没再套个()而是直接罗列在[ ],提取各个外()的值用[::2],内()用[1::2]。
    re_first取到的是首个匹配下的外()的内容,等同re('')[0],若需要首个匹配下的内()就不能用re_first了。
     
    s.driver还有.find_element_by_*的进阶版.ensure_element_by_css_selector('',state='clickable',timeout=7)等等,返回的WebElement对象,可以:
    什么都不干,坐等标签加载出来;提取内容和属性如.text、.get_attribute('');
    定位如.click()、.ensure_click()、.send_keys(Keys.CONTROL,'A')、.is_selected()、.is_displayed()。
    state参数用默认的present通常足矣,不行还可换用clickable、visible、invisible (waiting for loading...的场景,不必等加载完)。
    *******************分割线*******************
    杂项:
     
    s.driver.close()、.quit()、.back()、.forward()、.refresh():关闭选项卡、退出浏览器、后退前进刷新
    s.driver.title、.current_url、.page_source:当前视图的标题、网址、网页源代码
    s.driver.ensure_add_cookie({}型的cookies, override_domain=''):对浏览器当前访问过的各域站,都添加这个cookies。
     
    s.transfer_driver_cookies_to_session(),共享了cookies、User-Agent、proxies。
    反:s.transfer_session_cookies_to_driver(),requests暂只共享proxies给PhantomJS,chrome等新版。
     
    binary_location中自定义的Chrome路径,Quic移动版保留了插件及插件选项设置,首次运行后还保留了session,下次运行可跳过登录等环节,直接上s.transfer_driver_cookies_to_session();而安装版就没携带插件以及保留session。不过Quic版模拟登录一些网站如百度,或许存在元素定位不准的问题。用安装版还是Quic移动版,视网站而定。
    ****************************************分割线****************************************
    小众搜索(requests+parse,未结合selenium):
     
    from pprint import pprint
    from gevent import monkey;monkey.patch_all()
    from gevent.pool import Pool

    from requestium import Session
    from fake_useragent import UserAgent
    from urllib.parse import quote
     
    def spider1(word):
        s=Session('','chrome')
        response=s.get(f'http://bird.so/search?q={word}')
        xsrf=response.re_first('xsrf" value="((.|s)+?)"')
        s.headers={'referer':f'http://bird.so/search?q={quote(word)}',   #头里不能有中文
            'Cookie':f'_xsrf={xsrf}','Content-Type':'application/x-www-form-urlencoded'}
        return s,xsrf
     
    def spider2(s,xsrf,word,page):
        s.headers.update({'User-Agent':UserAgent().random})
        response=s.post('http://bird.so/fuck',data=dict(_xsrf=xsrf,q=word,page=page)).json()
        with open('E:/birdSo.txt','a',encoding='utf8') as f:
            for item in response['items']:    #输出为json样式可用pprint(response)
                f.write(' '.join([item['title'],item['formattedUrl'],item['snippet'],' ']))
     
    def main():
        s,xsrf=spider1(word)
        [p.spawn(spider2,s,xsrf,word,page) for page in range(1,7)]
        p.join()
     
    if __name__ == '__main__':
        p=Pool(size=9)
        word='爬虫'
        main()
    ****************************************分割线****************************************
    seleniumのloginedSession transfer to requests:
     
    Egのoschina:

    loginUrl='https://www.oschina.net/home/login'
    indexUrl='https://my.oschina.net'
    userName='904477955@qq.com'
    pwd='123456789cy'
     
    from requestium import Session,Keys
    from fake_useragent import UserAgent
     
    options={'arguments':['disable-infobars','headless'],  #无地址栏信息条&头,禁图,自定义路径
        'experimental_options':{'prefs':{'profile.managed_default_content_settings.images':2}},
        'binary_location': 'D:/Program Files/Browser/ChromeQuic/chrome.exe'}
    s=Session('C:/Program Files/Python36/chromedriver','chrome',7,options)
    driver=s.driver
     
    def loginByBrowser():
        driver.get(indexUrl)  #移动版Chrome保留有session,当前访问过的域名才能删掉其cookies
        driver.delete_all_cookies()
        driver.get(loginUrl)
        css=driver.ensure_element_by_css_selector
        css('#userMail').send_keys(userName)
        css('#userPassword').send_keys(pwd,Keys.ENTER)
        css('#MySpace')
        if not driver.re_first('退出'):print('登录失败')
     
    def toRequests():
        driver.get(indexUrl)    #存有众多网站的session,当前访问过的那个站点才被共享
        s.transfer_driver_cookies_to_session()    #之后默认用driver共享的UA,也可自定义
        driver.close();driver.quit()    #Quic移动版的Chrome,关闭和退出都要有
        response=s.get(indexUrl,headers={'User-Agent':UserAgent().random}).text
        if '个人资料修改' in response and '退出' in response:
            print('browser中该站点的session已共享给requests')
     
    if __name__ == '__main__':
        #loginByBrowser()  #首次启用本句,Quic移动版Chrome保留了session,再运行可注释
        toRequests()
    ****************************************分割线****************************************
    Egの百度:
    Quic移动版对百度的元素定位不准,此例用不保留session的安装版CentBrowser(Chrome内核)
     
    indexUrl='https://www.baidu.com/'
    userName='……'
    pwd='……'
     
    from requestium import Session,Keys
    from fake_useragent import UserAgent
     
    options={'arguments':['disable-infobars'],    #登录要识别验证码,故没用无头模式也没禁图
        'binary_location':'D:/Program Files/Browser/CentBrowser/Application/chrome.exe'}
    s=Session('C:/Program Files/Python36/chromedriver','chrome',7,options)
    driver=s.driver
     
    def loginByBrowser():
        driver.get(indexUrl)
        css=driver.ensure_element_by_css_selector
        css('#u1> a.lb').click()
        css('.tang-pass-footerBarULogin').click()
        css('[id$=userName]').send_keys(userName)
        css('[id$=password]').send_keys(pwd,Keys.ENTER)
        input('浏览器端手动输完验证码后,在本句句尾任敲一字母:')
        try:css('#TANGRAM__PSP_10__submit').click()
        except:pass
        css('.user-name')
        if not driver.re_first('退出'):print('登录失败')
     
    def toRequests():
        driver.get(indexUrl)
        s.transfer_driver_cookies_to_session()
        driver.quit()
        response=s.get(indexUrl,headers={'User-Agent':UserAgent().random}).text
        if '个人中心' in response and '退出' in response:
            print('browser中该站点的session已共享给requests')
     
    if __name__ == '__main__':
        loginByBrowser()
        toRequests()
    ****************************************分割线****************************************
    requests_html库:
    pip install requests-html==0.6.7,pyppeteer==0.0.10
     
    from requests_html import HTMLSession
     
    s=HTMLSession()
    html=s.get('http://python-requests.org').html
     
    links=html.absolute_links
    css=html.find('#beloved-features li',first=False)[0]   #.text、.attrs、.html
    html.render()   #.pyppeteer…CrashpadMetrics-active.pma:WinError 5
    js=html.search('Python 2 will retire in only {m} months!')['m']
    print(links,css,js,sep=' ')
  • 相关阅读:
    HDU4812 D Tree(树的点分治)
    BZOJ1834 [ZJOI2010]network 网络扩容(最小费用最大流)
    HDU4862 Jump(放大边权的费用流)
    SCU3185 Black and white(二分图最大点权独立集)
    HDU3729 I'm Telling the Truth(字典序最大的最大流)
    HDU3586 Information Disturbing(树形DP)
    HDU3657 Game(最小割)
    POJ3162 Walking Race(树形DP+尺取法+单调队列)
    SCU3312 Stockholm Knights(最大流)
    Codeforces 161D Distance in Tree(树的点分治)
  • 原文地址:https://www.cnblogs.com/scrooge/p/8205940.html
Copyright © 2011-2022 走看看