<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Selenium自動化|輕松爬取公眾號文章

          共 4188字,需瀏覽 9分鐘

           ·

          2020-09-25 08:37




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


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

          Selenium介紹

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


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

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

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


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

          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行是為了馬上會提到的?顯式等待
          import?time
          import?datetime

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

          上述的代碼就可以實(shí)現(xiàn)打開搜狗微信搜索的操作,接下來需要往搜索框里輸入文字,并且點(diǎn)擊“搜文章”(不直接點(diǎn)搜公眾號是因?yàn)橐呀?jīng)取消通過公眾號直接獲取相應(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è)定最長等待時(shí)間,在10s內(nèi)發(fā)現(xiàn)了輸入框已經(jīng)加載出來后就輸入公眾號名稱,這里我們以“早起Python”為例,并且根據(jù)“搜文章”按鈕的xpath獲取該位置并點(diǎn)擊,這里就用到了顯式等待。Selenium請求網(wǎng)頁等待響應(yīng)受到網(wǎng)速牽制,如果元素未加載全而代碼執(zhí)行過快就會意外報(bào)錯而終止,解決方式是等待

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

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


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



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

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

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

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

          由于涉及兩次遍歷則可以將解析信息包裝成函數(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:
          ????????#?獲取公眾號來源
          ????????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ā)表的日期如果較近可能會顯示“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:
          ????????#?如果遍歷到第十頁則跳出循環(huán)不需要點(diǎn)擊“下一頁”
          ????????break
          ????driver.find_element_by_id("sogou_next").click()


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


          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()


          效果如圖:



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


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

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


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



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

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

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

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

          作者:陳熹

          來源:早起Python



          _往期文章推薦_

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




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

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  玖玖黄色视频 | 免费黄色小视频网站 | 成人中文字幕在线视频 | 高清视频在线观看一区 | 超碰免费网 |