1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Selenium自動(dòng)化|輕松爬取公眾號(hào)文章

        共 4188字,需瀏覽 9分鐘

         ·

        2020-09-25 08:37




        大家好,今天我們來(lái)講點(diǎn)Selenium自動(dòng)化,你是否有特別喜歡的公眾號(hào)?你有想過(guò)如何將一個(gè)公眾號(hào)歷史文章全部文章爬下來(lái)學(xué)習(xí)嗎?現(xiàn)在我們就演示用Selenium實(shí)現(xiàn)這個(gè)功能。


        下面就來(lái)詳細(xì)講解如何一步步操作,文末附完整代碼。

        Selenium介紹

        Selenium是一個(gè)用于web應(yīng)用程序自動(dòng)化測(cè)試的工具,直接運(yùn)行在瀏覽器當(dāng)中,可以通過(guò)代碼控制與頁(yè)面上元素進(jìn)行交互,并獲取對(duì)應(yīng)的信息。Selenium很大的一個(gè)優(yōu)點(diǎn)是:不需要復(fù)雜地構(gòu)造請(qǐng)求,訪問(wèn)參數(shù)跟使用瀏覽器的正常用戶一模一樣,訪問(wèn)行為也相對(duì)更像正常用戶,不容易被反爬蟲(chóng)策略命中,所見(jiàn)即所得。而且在抓取的過(guò)程中,必要時(shí)還可人工干預(yù)(比如登錄、輸入驗(yàn)證碼等)。


        Selenium常常是面對(duì)一個(gè)嚴(yán)格反爬網(wǎng)站無(wú)從入手時(shí)的保留武器。當(dāng)然也有缺點(diǎn):操作均需要等待頁(yè)面加載完畢后才可以繼續(xù)進(jìn)行,所以速度要慢,效率不高(某些情況下使用headless和無(wú)圖模式會(huì)提高一點(diǎn)效率)。

        需求分析和代碼實(shí)現(xiàn)

        需求很明確:獲取一個(gè)公眾號(hào)全部推文的標(biāo)題、日期、鏈接。微信自身的推文功能只能通過(guò)其App查看,對(duì)App的抓取比較復(fù)雜。有一個(gè)很方便的替代途徑就是通過(guò)搜狗微信檢索。不過(guò)如果直接使用Requests等庫(kù)直接請(qǐng)求,會(huì)涉及的反爬措施有cookie設(shè)置,js加密等等,所以今天就利用Selenium大法!


        首先導(dǎo)入所需的庫(kù)和實(shí)例化瀏覽器對(duì)象:

        from?selenium?import?webdriver
        from?selenium.webdriver.common.by?import?By
        from?selenium.webdriver.support?import?expected_conditions?as?EC
        from?selenium.webdriver.support.wait?import?WebDriverWait
        #?導(dǎo)入第2-4行是為了馬上會(huì)提到的?顯式等待
        import?time
        import?datetime

        driver?=?webdriver.Chrome()
        driver.get('https://weixin.sogou.com/')

        上述的代碼就可以實(shí)現(xiàn)打開(kāi)搜狗微信搜索的操作,接下來(lái)需要往搜索框里輸入文字,并且點(diǎn)擊“搜文章”(不直接點(diǎn)搜公眾號(hào)是因?yàn)橐呀?jīng)取消通過(guò)公眾號(hào)直接獲取相應(yīng)文章的功能)


        wait?=?WebDriverWait(driver,?10)
        input?=?wait.until(EC.presence_of_element_located((By.NAME,?'query')))
        input.send_keys('早起Python')
        driver.find_element_by_xpath("http://input[@class='swz']").click()

        邏輯是設(shè)定最長(zhǎng)等待時(shí)間,在10s內(nèi)發(fā)現(xiàn)了輸入框已經(jīng)加載出來(lái)后就輸入公眾號(hào)名稱,這里我們以“早起Python”為例,并且根據(jù)“搜文章”按鈕的xpath獲取該位置并點(diǎn)擊,這里就用到了顯式等待。Selenium請(qǐng)求網(wǎng)頁(yè)等待響應(yīng)受到網(wǎng)速牽制,如果元素未加載全而代碼執(zhí)行過(guò)快就會(huì)意外報(bào)錯(cuò)而終止,解決方式是等待

        隱式等待是在嘗試發(fā)現(xiàn)某個(gè)元素的時(shí)候,如果沒(méi)能立刻發(fā)現(xiàn),就等待固定長(zhǎng)度的時(shí)間driver.implicitly_wait(10),顯示等待明確了等待條件,只有該條件觸發(fā),才執(zhí)行后續(xù)代碼,如這里我用到的代碼,當(dāng)然也可以用time模塊之間設(shè)定睡眠時(shí)間,睡完了再運(yùn)行后續(xù)代碼。

        跳轉(zhuǎn)了下一頁(yè)后可以發(fā)現(xiàn)不是所有的文章都由“早起Python”推送:


        另外只能獲取前10頁(yè)100條的結(jié)果,查看后續(xù)頁(yè)面需要微信掃碼登錄:



        因此從這里開(kāi)始,代碼的執(zhí)行邏輯為:

        • 先遍歷前10頁(yè)100個(gè)文章的作者名字,如果不是“早起Python”則跳過(guò),是則獲取對(duì)應(yīng)的標(biāo)題名字、發(fā)布日期和鏈接

        • 第10頁(yè)遍歷完成后自動(dòng)點(diǎn)擊登錄,此時(shí)需要人工介入,掃碼完成登錄

        • 代碼檢測(cè)登錄是否完成(可以簡(jiǎn)化為識(shí)別“下一頁(yè)”按鈕是否出現(xiàn)),如果登錄完成則繼續(xù)從11頁(yè)遍歷到最后一頁(yè)(沒(méi)有“下一頁(yè)”按鈕)

        由于涉及兩次遍歷則可以將解析信息包裝成函數(shù):


        num?=?0

        def?get_news():
        ????global?num?#?放全局變量是為了給符合條件的文章記序
        ????time.sleep(1)
        ????news_lst?=?driver.find_elements_by_xpath("http://li[contains(@id,'sogou_vr_11002601_box')]")
        ????for?news?in?news_lst:
        ????????#?獲取公眾號(hào)來(lái)源
        ????????source?=?news.find_elements_by_xpath('div[2]/div/a')[0].text
        ????????if?'早起'?not?in?source:
        ????????????continue
        ????????num?+=?1
        ????????#?獲取文章標(biāo)題
        ????????title?=?news.find_elements_by_xpath('div[2]/h3/a')[0].text
        ????????#?獲取文章發(fā)表日期
        ????????date?=?news.find_elements_by_xpath('div[2]/div/span')[0].text
        ????????#?文章發(fā)表的日期如果較近可能會(huì)顯示“1天前”?“12小時(shí)前”?“30分鐘前”
        ????????#?這里可以用`datetime`模塊根據(jù)時(shí)間差求出具體時(shí)間
        ????????#?然后解析為`YYYY-MM-DD`格式
        ????????if?'前'?in?date:
        ????????????today?=?datetime.datetime.today()
        ????????????if?'天'?in?date:
        ????????????????delta?=?datetime.timedelta(days=int(date[0]))
        ????????????elif?'小時(shí)'?in?date:
        ????????????????delta?=?datetime.timedelta(hours=int(date.replace('小時(shí)前',?'?')))
        ????????????else:
        ????????????????delta?=?datetime.timedelta(minutes=int(date.replace('分鐘前',?'?')))
        ????????????date?=?str((today?-?delta).strftime('%Y-%m-%d'))
        ????????date?=?datetime.datetime.strptime(date,?'%Y-%m-%d').strftime('%Y-%m-%d')
        ????????#?獲取url
        ????????url?=?news.find_elements_by_xpath('div[2]/h3/a')[0].get_attribute('href')
        ????????print(num,?title,?date)
        ????????print(url)
        ????????print('-'?*?10)

        for?i?in?range(10):
        ????get_news()
        ????if?i?==?9:
        ????????#?如果遍歷到第十頁(yè)則跳出循環(huán)不需要點(diǎn)擊“下一頁(yè)”
        ????????break
        ????driver.find_element_by_id("sogou_next").click()


        接下來(lái)就是點(diǎn)擊“登錄”,然后人工完成掃碼,可以利用while True檢測(cè)登錄是否成功,是否出現(xiàn)了下一頁(yè)按鈕,如果出現(xiàn)則跳出循環(huán),點(diǎn)擊“下一頁(yè)”按鈕并繼續(xù)后面的代碼,否則睡3秒后重復(fù)檢測(cè):


        driver.find_element_by_name('top_login').click()
        while?True:
        ????try:
        ????????next_page?=?driver.find_element_by_id("sogou_next")
        ????????break
        ????except:
        ????????time.sleep(3)
        next_page.click()


        效果如圖:



        然后就是重新遍歷文章了,由于不知道最后一頁(yè)是第幾頁(yè)可以使用while循環(huán)反復(fù)調(diào)用解析頁(yè)面的函數(shù)半點(diǎn)擊“下一頁(yè)”,如果不存在下一頁(yè)則結(jié)束循環(huán):


        while?True:
        ????get_news()
        ????try:
        ????????driver.find_element_by_id("sogou_next").click()
        ????except:
        ????????break

        #?最后退出瀏覽器即可
        driver.quit()


        是不是少了點(diǎn)什么?對(duì),就是數(shù)據(jù)存儲(chǔ),在爬下來(lái)數(shù)據(jù)之后和之前一樣利用openpyxl存儲(chǔ)到excel中即可(如果不想用此模塊的話也可以改用 csv 或者 pandas 保存表格文件):



        現(xiàn)在我們就有了該公眾號(hào)呢的全部文章標(biāo)題和URL,還可以使用Pdfkit將每一個(gè)URL轉(zhuǎn)成PDF格式,本文就不再展開(kāi)敘述,可以參考之前的文章:

        一鍵下載:將知乎專欄導(dǎo)出成電子書(shū)

        如果對(duì)本次selenium自動(dòng)化感興趣的化可以下載源碼深入學(xué)習(xí),只需修改對(duì)應(yīng)公眾號(hào)名稱就可以使用啦:
        https://pan.baidu.com/s/1ZDSDF84fOWxJl2UbZU_L_Q??
        密碼: 8apj

        注1:Selenium瀏覽器自動(dòng)化需要依賴ChromeDriver,ChromeDriver要和你電腦上的Chrome版本一致,詳細(xì)的配置請(qǐng)自行查詢
        注2:本文代碼未考慮火狐瀏覽器,配置和代碼會(huì)和Chrome瀏覽器略有不同

        作者:陳熹

        來(lái)源:早起Python



        _往期文章推薦_

        【編程課堂】selenium祖?zhèn)髋老x(chóng)利器




        瀏覽 72
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            蜜臀在线视频| 成人午夜福利电影| 精品人妻一区二区三区四区不卡在 | 国内精品久久久久久久久久| 七十路の高齡熟妇无码| 99无码秘蜜桃人妻一区二区三区| 新超碰在线观看| 人成无码| 99在线视频精品| 亚洲无码在线观看视频|