分享一個零基礎快速爬取數據的工具


今天介紹下如何使用pyppeteer抓取網頁的數據。pyppeteer是web應用自動化測試的具,可以直接運行在瀏覽器中,通過代碼控制與頁面上元素進行交互,並獲取對應的信息。

以前我們我們爬取數據都是通過寫代碼爬取,當待爬取的網站需要登錄時,我們需要在代碼中模擬登錄;當爬取過快需要驗證時,我們需要在代碼中實現驗證邏輯;當ip被封時,還需要有自己的動態ip庫。待爬網站的反爬策略越多,我們爬取的成本就越大。總之,用寫代碼的方式爬取數據需要構造比較復雜的請求,想盡一切辦法將爬蟲偽裝成真實的用戶。

使用pyppeteer這樣的工具,就可以在很大程度上解決上面的問題。同時,還有一個優點是所見即所得,不需要再去研究網頁復雜的請求結構。當然這類工具也是優缺點的,它增加了你去理解網頁上各種元素以及交互的成本。所以我覺得這類工具最適合在短平快的爬蟲場景中使用。比如我在最近的工作中就遇到兩次這樣的情況,想爬一些特別簡單的數據來提升工作效率,但又不想研究網頁是如何構造請求的,用這種所見即所得的工具就可以快速抓取想要的數據。

下面我們以“抓取百度搜索數據”例子我介紹一下pyppeteer的使用。正式介紹前我們先來看下爬取效果:

安裝pyppeteer

python3 -m pip install pyppeteer

安裝完成后,執行pyppeteer-install命令安裝最新版本的 Chromium 瀏覽器。根據官方文檔的說明,安裝pyppeteer需要Python3.6以上的版本。

由於pyppeteer是基於asyncio實現的,所以我們的代碼中也會用async/await來寫代碼,之前沒寫過的朋友也不用擔心,基本不影響對pyppeteer的使用,有必要的話以后再單獨寫篇文章介紹。

首先,用pyppeteer啟動 chrome 進程

from pyppeteer import launch
# headless 顯示瀏覽器 # --window-size 設置窗體大小 browser = await launch({'headless': False,  'args': ['--window-size=%d,%d' % (width, height)]  }) 

然后,打開一個新的標簽,並訪問百度

# 打開新頁面
page = await browser.newPage() # 設置內容顯示大小 await page.setViewport({"width": width, "height": height}) # 訪問百度 await page.goto('https://www.baidu.com') 

打開百度網站后,下一步就要向搜索輸入框輸入內容,首先要找到輸入框的html標簽 從上圖可以看到,<input id="kw" name="wd" class="s_ipt" value="" maxlength="255" autocomplete="off">代碼代表搜索輸入框,該標簽的 class 是s_ipt,那下面我們就通過type函數找到該標簽,並鍵入需要搜索的內容

# 將對應的 selector 填入 python,通過.s_ipt找到輸入框html標簽
await page.type('.s_ipt', 'python') 

這里我們搜的是python,有了輸入后就可以點擊“百度一下”按鈕來發起搜索。找按鈕的方式與上面一樣 可以看到<input type="submit" id="su" value="百度一下" class="bg s_btn">代碼代表“百度一下”的按鈕,該標簽的 id 是su,下面就調用click函數找到該標簽,並點擊

# 通過#su找到“百度一下”按鈕html標簽
await page.click('#su') 

這里需要注意su前面是#而不是.,因為在html標簽中它用id表示而不是class,這里涉及html selector的內容,不清楚的朋友可以簡單補一下。

執行完上面的代碼,我們可以看到搜索結果了,調用screenshot方法將當前頁面保存

await page.screenshot({'path': 'example.png'})

效果如下: 接下來我們就獲取網頁內容,並解析每條結果

# 獲取網頁內容
content = await page.content() # 解析 output_search_result(content) 

通過BeatifulSoup解析每條結果的標題與鏈接

def output_search_result(html):
 search_bs = BeautifulSoup(html, 'lxml')   all_result = search_bs.find_all("div", {'class': "result c-container"})  for single_res in all_result:  title_bs = single_res.find("a")  title_url = title_bs.get('href')  title_txt = title_bs.get_text()   print(title_txt, title_url) 

輸出的內容如下

python官方網站 - Welcome to Python.org http://www.baidu.com/link?url=OqtoElo8HW1GdOgAlqdCTz2lpewFLf0HlbnGdyAKD06BfPbw0fsJ_N5fclxx-q1D
Python 基礎教程 | 菜鳥教程 http://www.baidu.com/link?url=IooFgJjdec1qPXhGhF7tur-z2Qt_43RkK3L-9cp8oB-0i2w7unKzLayLjg3zSQeKQieA49JFejMjqTM-TSY3V_ Python3 * 和 ** 運算符_python_極客點兒-CSDN博客 http://www.baidu.com/link?url=H3VdAQRAbTkN9jGJGkvhIFTdg48O-b5yib7vCquWyg1-6FZwBVHnJ5iiUYQkjbf-8IuLfOwDXoUMDOdMvXNHkzejts4uRHrczgQqekgQuFy Python教程 - 廖雪峰的官方網站 http://www.baidu.com/link?url=piu0nEfXNvkLhWchcdX2EjJvIkQ5beq2_uYH_B7u2vjYO82BZwr8SXgDxnVLZYgGL8xuR_ovjg2cAYfPS9AmLtqUQP-TrWuJWHNqYbxdQnUPTy_VPp8sSBdCaYBl9YDX Python3 教程 | 菜鳥教程 http://www.baidu.com/link?url=bx1rMrzxC69Sp0zY08-VhFs40QQ8UFxZdvmZVFcKYkCG2mdojhAMjk5ulKBKwQm77x8vMyOeowW_bNtoP35m3q 你都用 Python 來做什么? - 知乎 http://www.baidu.com/link?url=YTMr1ycFjtkWx8lgJ_PT3-kF50vYI6Yibh4o69WL_afBSOkkZmGxexxIKXY3fGAX8X2-AaFbI4jL1vJbKMJrsK Python基礎教程,Python入門教程(非常詳細) http://www.baidu.com/link?url=elAepKY7rhULzTPuwKvk8Cxx21K5D0Ey7-Wj9TZgN49MyasPOXtLYfWbp46QZQie 

這樣,我們的抓取數據的目的已經達到了,當然我們還可以繼續拓展下,多用用pyppeteer,比如:我們可以點擊下一頁,抓取下一頁的內容

# next page
# 為了點擊“下一頁”,需要將當前頁面滑到底部 dimensions = await page.evaluate('window.scrollTo(0, window.innerHeight)') # 點擊“下一頁”按鈕 await page.click('.n') # 獲取第二頁的內容 content = await page.content() # 解析 output_search_result(content) 

操作與之前類似,注釋寫的也比較清楚,我就不再贅述了。最后可以調用await browser.close()代碼關閉瀏覽器。上述代碼可以定義需要定義在一個async函數中,如:

async def main():
 # ... 抓取代碼 

然后通過下面代碼

asyncio.get_event_loop().run_until_complete(main())

調用main函數。

pyppeteer的用法就介紹到這里了,類似的工具還有很多,比如:Selenium,我也試了下,確實如網上所說配置上面需要花些功夫,有興趣的朋友可以自行嘗試。希望今天的內容對你有用。關注公眾號回復關鍵字 爬蟲 獲取完整源碼

歡迎公眾號「渡碼」,輸出別地兒看不到的干貨。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM