一. 內容簡介
python爬取robomaster論壇文章數據。
二. 軟件環境
2.1vsCode
2.2Anaconda
version: conda 22.9.0
2.3代碼
三.主要流程
3.1 接口分析,以及網頁結構分析
# 這是文章鏈接,其實id就是文章的id
# https://bbs.robomaster.com/forum.php?mod=viewthread&tid=9234
# 文章結構
# 大疆這個文章,在訪問網站時候,他會把文章內容在服務端拼接好,是沒辦法直接拿到接口數據的,
# 第一個方面就是,urllib訪問時候,拿到整個網頁結構,這個結構是不帶js執行的,雖然數據都有,但是是和瀏覽器里面有些定位不太一樣的,在用xpath解析時候,經常找不到,有點不太方便
# 第二個方面,就是因為里面有些內容需要登錄,這個登錄有兩種驗證方式,一種是token,一種是cookie,大疆是cookie,所以我們需要在請求頭中假如cooke訪問,分別用urllib和elenium實現
3.2 通過urllib攜帶cookie爬取網頁結構
import urllib.request
from lxml import etree
import json
from selenium.webdriver.common.by import By
from selenium import webdriver
import random
import time
import pyautogui
from datetime import datetime
import ssl
import re
import urllib.request
def urllibRequest(url):headers = {'Cookie':'換成自己的,直接去網頁請求里面復制','User-Agent':'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1'}# 創建一個不驗證證書的上下文對象context = ssl._create_unverified_context()request = urllib.request.Request(url=url, headers=headers)response = urllib.request.urlopen(request, context=context) # 在這里傳入context參數content = response.read().decode('UTF-8')return contenturl = "https://bbs.robomaster.com/forum.php?mod=viewthread&tid=9234"
content = urllibRequest(url)
print(content)
里面有一點需要注意的就是,這個網頁結構如果不能解析的話,要加這個,里面xml會報錯,替換一下就好
content_without_declaration = re.sub(r'^<\?xml.*\?>', '', content)
html_tree = etree.HTML(content_without_declaration)
3.3 通過selenium攜帶cookie爬取網頁結構
直接給selenium加個請求頭
import urllib.request
from lxml import etree
import json
from selenium.webdriver.common.by import By
from selenium import webdriver
import random
import time
import pyautogui
from datetime import datetime
import randomdef seleniumRequest(url,chrome_path,waitTime): headers = {'User-Agent':'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1''Cookie':'換自己的'}options = webdriver.ChromeOptions()# 添加cookie到瀏覽器中options.add_experimental_option('excludeSwitches', ['enable-automation'])options.add_experimental_option('useAutomationExtension', False)# 添加Header到options中options.add_argument(f'user-agent={headers["User-Agent"]}')options.add_argument(f'cookie={headers["Cookie"]}')# 谷歌瀏覽器exe位置options.binary_location = chrome_path# 是否要啟動頁面# options.add_argument("--headless") # 啟用無頭模式# GPU加速有時候會出bugoptions.add_argument("--disable-gpu") # 禁用GPU加速options.add_argument("--disable-blink-features=AutomationControlled")driver = webdriver.Chrome(options=options)driver.execute_cdp_cmd('Page.addScriptToEvaluateOnNewDocument',{'source': 'Object.defineProperty(navigator, "webdriver", {get: () => undefined})'})# 啟動要填寫的地址,這就啟動瀏覽器driver.get(url)# 這是關閉瀏覽器# 等待頁面加載,可以根據實際情況調整等待時間driver.implicitly_wait(waitTime)# 獲取完整頁面結構full_page_content = driver.page_source# 關閉瀏覽器driver.quit()return full_page_content
# # 處理完整頁面結構
# print(full_page_content)
url = "https://bbs.robomaster.com/forum.php?mod=viewthread&tid=9234"
# print(url)chrome_path = r"C:\Program Files\Google\Chrome\Application\chrome.exe"
waitTime = 8
# 獲取網頁結構
# 通過selenium調用瀏覽器訪問
content = seleniumRequest(url,chrome_path,waitTime)
print(content)
3.4 網頁結構定位
一般都是通過xpath語法,一個div下面如果有多個類,我xpath就選不到了,可以用下面這個
//div[contains(@class, 'example')]
還有一種方式,可以用谷歌瀏覽器里面的工具,就不用自己一個一個選了
還有就是xpath選取得結構,用txt保存下來里面代碼,包括結構
# # 解析對應數據
# contents = html_tree.xpath("//div[@class='message']")[0]
# print(contents)# # # 將選定的div元素轉換為字符串
# div_html = etree.tostring(contents, encoding="unicode")# # print(div_html)
# # # 將HTML保存為文件
# with open('output.txt', 'w', encoding='utf-8') as f:
# f.write(div_html)