动态网页抓取——学习笔记
目錄
1 動態抓取技術簡介
2 解析真實地址抓取
3 通過Selenium模擬瀏覽器抓取
3.1 Selenium的基本介紹
3.2 Selenium實踐案例
3.3 Selenium獲取文章的所有評論
3.4 Selenium的高級操作
3.4.1 控制CSS
3.4.2 限制圖片的加載
3.4.3 控制JavaScript的運行
參考資料
1 動態抓取技術簡介
- 異步更新技術——AJAX
AJAX(Asynchronous Javascript And XML,異步JavaScript和XML)的價值在于通過在后臺與服務器進行少量的數據交換就可以使網頁實現異步更新。這意味著可以在不重新加載整個網頁的情況下對網頁的某部分進行更新。一方面減少了網頁重復內容的下載,另一方面節省了流量,因此AJAX得到了廣泛的使用。
爬取使用AJAX加載的動態網頁里的動態加載的內容有兩種動態網頁抓取的方法:
- 通過瀏覽器審查元素解析真實網頁地址
- 使用Selenium模擬瀏覽器的方法
2 解析真實地址抓取
以《Python網絡爬蟲從入門到實踐(第2版)》作者博客的Hello World文章為例,目標是抓取文章下的所有評論。文章網址為:
http://www.santostang.com/2018/07/04/hello-world/
步驟01 打開“檢查”功能。用Chrome瀏覽器打開Hello World文章。右擊頁面的任意位置,在彈出的快彈菜單中單擊“檢查”命令。
步驟02 找到真實的數據地址。單擊頁面中的Network選項,然后刷新網頁。此時,Network會顯示瀏覽器從網頁服務器中得到的所有文件,一般這個過程成為“抓包”。
從文件中快速找到評論數據所在文件的方法:search評論內容可以快速定位具體的評論所在位置的文件。
步驟03 爬取真實評論數據地址。既然找到了真實的地址,接下來就可以直接用requests請求這個地址獲取數據了。
步驟04 從json數據中提取評論。可以使用json庫解析數據,從中提取想要的數據。
import requests import jsonlink = "https://api-zero.livere.com/v1/comments/list?callback=jQuery112408626354130815113_1646567623361&limit=10&repSeq=4272904&requestPath=/v1/comments/list&consumerSeq=1020&livereSeq=28583&smartloginSeq=5154&code=&_=1646567623363" headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.51 Safari/537.36'} r = requests.get(link, headers=headers) # 獲取json的string json_string = r.text json_string = json_string[json_string.find('{'):-2] # 從第一個左大括號提取,最后的兩個字符-括號和分號不取 json_data = json.loads(json_string) comment_list = json_data['results']['parents'] for eachone in comment_list:message = eachone['content']print(message)接下來可以用for循環爬取多頁評論數據,可以通過對比不同頁面真實地址,發現其參數的不同之處,通過改變折現參數值實現換頁。
import requests import jsondef single_page_comment(link):headers = {'User-Agent': 'https://api-zero.livere.com/v1/comments/list?callback=jQuery112407919796508302595_1646571637355&limit=10&offset=2&repSeq=4272904&requestPath=/v1/comments/list&consumerSeq=1020&livereSeq=28583&smartloginSeq=5154&code=&_=1646571637361'}r = requests.get(link, headers=headers)# 獲取json的stringjson_string = r.textjson_string = json_string[json_string.find('{'):-2] # 從第一個左大括號提取,最后的兩個字符-括號和分號不取json_data = json.loads(json_string)comment_list = json_data['results']['parents']for eachone in comment_list:message = eachone['content']print(message)max_comments = 50 # 設置要爬取的最大評論數 for page in range(1,max_comments // 10 + 1):link1 = "https://api-zero.livere.com/v1/comments/list?callback=jQuery112407919796508302595_1646571637355&limit=10&offset="link2 = "&repSeq=4272904&requestPath=/v1/comments/list&consumerSeq=1020&livereSeq=28583&smartloginSeq=5154&code=&_=1646571637361"page_str = str(page)link = link1 + page_str + link2print(link)single_page_comment(link)3 通過Selenium模擬瀏覽器抓取
有些網站非常復雜,使用“檢查”功能很難找到調用的網頁地址。除此之外,有些數據的真實地址的URL也十分復雜,有些網站為了規避這些抓取會對地址進行加密,造成其中的一些變量讓人摸不著頭腦,因此,這里介紹另一種方法,即使用瀏覽器渲染引擎。直接使用瀏覽器在顯示網頁時解析HTML、應用CSS樣式并執行JavaScript的語句。通俗來講就是使用瀏覽器渲染方法將爬取動態頁面變成爬取靜態頁面。
在這里,使用Python的Selenium庫模擬瀏覽器完成抓取。Selenium是一個用于Web應用程序測試的工具。
3.1 Selenium的基本介紹
瀏覽器驅動下載地址:
Chrome: https://sites.google.com/chromium.org/driver/
Edge: Microsoft Edge Driver - Microsoft Edge Developer
Firefox: Releases · mozilla/geckodriver · GitHub
Safari: WebDriver Support in Safari 10 | WebKit
使用Selenium打開瀏覽器和一個網頁,代碼如下:
from selenium import webdriverdriver = webdriver.Firefox() driver.get("http://www.santostang.com/2018/07/04/hello-world/")3.2 Selenium實踐案例
步驟01 找到評論的HTML代碼標簽。使用Chrome打開文章頁面,右擊頁面,在彈出的快捷菜單中單擊“檢查”命令。
步驟02 嘗試獲取一條評論數據。在原來打開頁面的代碼數據上使用以下代碼,獲取第一條評論數據。
from selenium import webdriverdriver = webdriver.Firefox() driver.get("http://www.santostang.com/2018/07/04/hello-world/") # 轉化iframe driver.switch_to.frame(driver.find_element(by='css selector', value='iframe[title="livere-comment"]')) # 獲取css標簽為div.reply-content comment = driver.find_element(by='css selector', value='div.reply-content') content = comment.find_element(by='tag name', value='p')print(content.text)3.3 Selenium獲取文章的所有評論
如果要獲取所有評論,需要腳本程序能夠自動點擊“+10查看更多”,這樣才能將所有評論顯示出來。因此,我們需要找到“+10查看更多”的元素地址,然后讓Selenium模擬單擊并加載評論。具體代碼如下:
from selenium import webdriver import timedriver = webdriver.Firefox() driver.implicitly_wait(10) # 隱性等待,最長等10秒 driver.get("http://www.santostang.com/2018/07/04/hello-world/") time.sleep(5) # 下滑到頁面底部(左下角) driver.execute_script("window.scrollTo(0,document.body.scrollHeight);") print("wait for 3 seconds") time.sleep(3) for i in range(1, 19):# 轉換iframe,再找到查看更多,點擊driver.switch_to.frame(driver.find_element(by="css selector", value="iframe[title='livere-comment']"))# load_more = driver.find_element(by="css selector", value="button[data-page=\'%d\']'%i")if i > 11:x_path = './/div[@class="more-wrapper"]/button[' + str(i - 9) + ']'else:x_path = './/div[@class="more-wrapper"]/button[' + str(i) + ']'load_more = driver.find_element(by="xpath", value=x_path)load_more.send_keys("Enter") # 點擊前先按下Enter,可以解決因跳轉點擊時出現失去焦點而導致的click單擊無效的情況load_more.click()# 把iframe又轉回去driver.switch_to.default_content()print("Click and waiting loading --- please waiting for 5s")time.sleep(5)driver.switch_to.frame(driver.find_element(by="css selector", value="iframe[title='livere-comment']"))comments = driver.find_elements(by="css selector", value="div.reply-content")for each_comment in comments:content = each_comment.find_element(by="tag name", value="p")print(content.text)driver.switch_to.default_content()driver.execute_script("window.scrollTo(0,document.body.scrollHeight);")time.sleep(2)Selenium的常見操作元素方法如下:
- Clear:清除元素的內容
- send_keys:模擬按鍵輸入
- Click:單擊元素
- Submit:提交表單
Selenium除了可以實現簡單的鼠標操作,還可以實現復雜的雙擊、拖拽等操作。此外,Selenium還可以獲得網頁中各個元素的大小,甚至可以進行模擬鍵盤的操作。
3.4 Selenium的高級操作
常用的加快Selenium的爬取速度的方法有:
- 控制CSS的加載
- 控制圖片文件的顯示
- 控制JavaScript的運行
3.4.1 控制CSS
在抓取過程中僅僅抓取頁面的內容,CSS樣式文件是用來控制頁面的外觀和元素放置位置的,對內容并沒有影響,所以我們可以通過限制網頁加載CSS,從而較少抓取時間,其代碼如下:
# 控制CSS from selenium import webdriver# 使用fp控制CSS的加載 fp = webdriver.FirefoxOptions() fp.set_preference("permissions.default.stylesheet", 2) driver = webdriver.Firefox(options=fp) driver.get("http://www.santostang.com/2018/07/04/hello-world/")3.4.2 限制圖片的加載
如果不需要抓取網頁上的圖片,最好可以禁止圖片加載,限制圖片的加載可以幫助我們極大地提高網絡爬蟲的效率。
# 限制圖片的加載 from selenium import webdriverfp = webdriver.FirefoxOptions() fp.set_preference("permissions.default.image", 2) driver = webdriver.Firefox(options=fp) driver.get("http://www.santostang.com/2018/07/04/hello-world/")3.4.3 控制JavaScript的運行
如果需要抓取的內容不是通過JavaScript動態加載得到的,我們可以通過禁止JavaScript的執行來提高抓取的效率。因為大多數網頁都會利用JavaScript異步加載很多的內容,這些內容不僅是我們不需要的,它們的加載還浪費了時間。
# 限制JavaScript的執行 from selenium import webdriver fp=webdriver.FirefoxOptions() fp.set_preference("javascript.enabled",False) driver=webdriver.Firefox(options=fp) driver.get("http://www.santostang.com/2018/07/04/hello-world/")參考資料
[1] 唐松.2019.Python網絡爬蟲從入門到實踐(第2版)[M].北京:機械工業出版社
總結
以上是生活随笔為你收集整理的动态网页抓取——学习笔记的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vue项目token放在哪里_关于vue
- 下一篇: C++包扩展_利用 MATLAB Cod