Python+Selenium自動化爬取攜程動態加載游記

1. 引言

在旅游行業數據分析、輿情監測或競品研究中,獲取攜程等平臺的游記數據具有重要價值。然而,攜程的游記頁面通常采用動態加載(Ajax、JavaScript渲染),傳統的**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Requests</font>**+**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">BeautifulSoup</font>**方案難以直接獲取完整數據。

解決方案:使用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Selenium</font>**模擬瀏覽器行為,配合**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">BeautifulSoup</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">lxml</font>**解析動態加載的游記內容。本文將詳細介紹如何利用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">Python+Selenium</font>**爬取攜程動態加載的游記,并存儲至**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">CSV</font>**文件。

2. 技術選型與工具準備

2.1 技術棧

  • Python 3.8+(推薦使用最新穩定版)
  • Selenium(瀏覽器自動化工具)
  • BeautifulSoup4(HTML解析庫)
  • Pandas(數據存儲與處理)
  • ChromeDriver(與Chrome瀏覽器配合使用)

2.2 環境安裝

2.3 下載瀏覽器驅動

  • ChromeDriver:下載地址(需與本地Chrome版本匹配)
  • GeckoDriver(Firefox):下載地址

3. 爬取攜程動態加載游記的步驟

3.1 分析攜程游記頁面結構

目標URL示例(以“北京”為例):

https://you.ctrip.com/travels/beijing1/t3.html

關鍵觀察點

  1. 動態加載:游記列表通過滾動或點擊“加載更多”動態獲取。
  2. Ajax請求:可通過瀏覽器開發者工具(F12→Network→XHR)查看數據接口。
  3. 反爬機制
    • User-Agent檢測
    • IP限制(需代理或控制請求頻率)
    • 登錄驗證(部分內容需登錄)

3.2 Selenium 模擬瀏覽器操作

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import pandas as pd
from bs4 import BeautifulSoup# 配置ChromeDriver路徑
driver_path = "chromedriver.exe"  # 替換為你的驅動路徑
options = webdriver.ChromeOptions()
options.add_argument("--headless")  # 無頭模式(可選)
options.add_argument("--disable-gpu")
options.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")driver = webdriver.Chrome(executable_path=driver_path, options=options)

3.3 訪問目標頁面并滾動加載數據

def scroll_to_bottom(driver, max_scroll=5):"""模擬滾動加載"""for _ in range(max_scroll):driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")time.sleep(2)  # 等待數據加載url = "https://you.ctrip.com/travels/beijing1/t3.html"
driver.get(url)
scroll_to_bottom(driver)  # 滾動加載更多游記

3.4 解析游記數據

def parse_travel_notes(driver):soup = BeautifulSoup(driver.page_source, 'html.parser')notes = soup.find_all('div', class_='journalslist')  # 游記列表容器data = []for note in notes:title = note.find('a', class_='journal-title').get_text(strip=True)author = note.find('a', class_='nickname').get_text(strip=True)date = note.find('span', class_='time').get_text(strip=True)views = note.find('span', class_='num').get_text(strip=True)content = note.find('p', class_='journal-content').get_text(strip=True)data.append({"標題": title,"作者": author,"發布時間": date,"閱讀量": views,"內容摘要": content})return datatravel_data = parse_travel_notes(driver)

3.5 存儲數據至CSV

df = pd.DataFrame(travel_data)
df.to_csv("ctrip_travel_notes.csv", index=False, encoding="utf_8_sig")  # 避免中文亂碼

4. 完整代碼實現

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
import pandas as pd
import time
from selenium.webdriver.chrome.options import Optionsdef scroll_to_bottom(driver, max_scroll=5):"""模擬滾動加載"""for _ in range(max_scroll):driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")time.sleep(2)def parse_travel_notes(driver):"""解析游記數據"""soup = BeautifulSoup(driver.page_source, 'html.parser')notes = soup.find_all('div', class_='journalslist')data = []for note in notes:title = note.find('a', class_='journal-title').get_text(strip=True)author = note.find('a', class_='nickname').get_text(strip=True)date = note.find('span', class_='time').get_text(strip=True)views = note.find('span', class_='num').get_text(strip=True)content = note.find('p', class_='journal-content').get_text(strip=True)data.append({"標題": title,"作者": author,"發布時間": date,"閱讀量": views,"內容摘要": content})return datadef main():# 代理配置proxyHost = "www.16yun.cn"proxyPort = "5445"proxyUser = "16QMSOML"proxyPass = "280651"# 初始化瀏覽器配置options = Options()# 設置User-Agentoptions.add_argument("user-agent=Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36")# 設置代理(帶認證)proxy_options = {'proxy': {'http': f'http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}','https': f'https://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}','no_proxy': 'localhost,127.0.0.1'}}# 添加代理擴展(適用于需要認證的代理)from selenium.webdriver.chrome.service import Servicefrom selenium.webdriver.common.proxy import Proxy, ProxyType# 方法1:使用ChromeOptions添加代理(基礎方法,可能不支持認證)# options.add_argument(f'--proxy-server=http://{proxyUser}:{proxyPass}@{proxyHost}:{proxyPort}')# 方法2:使用插件方式添加認證代理(推薦)# 需要先創建一個代理認證插件manifest_json = """{"version": "1.0.0","manifest_version": 2,"name": "Chrome Proxy","permissions": ["proxy","tabs","unlimitedStorage","storage","<all_urls>","webRequest","webRequestBlocking"],"background": {"scripts": ["background.js"]},"minimum_chrome_version":"22.0.0"}"""background_js = """var config = {mode: "fixed_servers",rules: {singleProxy: {scheme: "http",host: "%s",port: parseInt(%s)},bypassList: ["localhost"]}};chrome.proxy.settings.set({value: config, scope: "regular"}, function() {});function callbackFn(details) {return {authCredentials: {username: "%s",password: "%s"}};}chrome.webRequest.onAuthRequired.addListener(callbackFn,{urls: ["<all_urls>"]},['blocking']);""" % (proxyHost, proxyPort, proxyUser, proxyPass)# 創建臨時插件目錄import osimport tempfileimport zipfileplugin_dir = tempfile.mkdtemp()with open(os.path.join(plugin_dir, "manifest.json"), 'w') as f:f.write(manifest_json)with open(os.path.join(plugin_dir, "background.js"), 'w') as f:f.write(background_js)# 打包插件proxy_plugin_path = os.path.join(plugin_dir, "proxy_auth_plugin.zip")with zipfile.ZipFile(proxy_plugin_path, 'w') as zp:zp.write(os.path.join(plugin_dir, "manifest.json"), "manifest.json")zp.write(os.path.join(plugin_dir, "background.js"), "background.js")# 添加插件到ChromeOptionsoptions.add_extension(proxy_plugin_path)try:# 初始化瀏覽器(帶代理)driver = webdriver.Chrome(executable_path="chromedriver.exe", options=options)# 訪問頁面并滾動加載url = "https://you.ctrip.com/travels/beijing1/t3.html"driver.get(url)scroll_to_bottom(driver)# 解析數據travel_data = parse_travel_notes(driver)# 存儲數據df = pd.DataFrame(travel_data)df.to_csv("ctrip_travel_notes.csv", index=False, encoding="utf_8_sig")print("數據爬取完成,已保存至 ctrip_travel_notes.csv")finally:driver.quit()# 清理臨時插件文件import shutilshutil.rmtree(plugin_dir)if __name__ == "__main__":main()

5. 進階優化

5.1 反反爬策略

  • 隨機User-Agent:使用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">fake_useragent</font>**庫動態切換UA。
  • IP代理池:結合**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">requests</font>**+**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">proxies</font>**繞過IP限制。
  • 模擬登錄:處理需要登錄才能查看的游記。

5.2 數據增強

  • 情感分析:使用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">SnowNLP</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">TextBlob</font>**分析游記情感傾向。
  • 關鍵詞提取:利用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">jieba</font>**分詞提取熱門景點關鍵詞。

5.3 分布式爬蟲

  • Scrapy+Redis:提升爬取效率。
  • 多線程/異步爬取:使用**<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">asyncio</font>****<font style="color:rgb(64, 64, 64);background-color:rgb(236, 236, 236);">aiohttp</font>**優化請求速度。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/89563.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/89563.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/89563.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ESP8266服務器建立TCP連接失敗AT+CIPSTART=“TCP“,“192.168.124.1“,8080 ERROR CLOSED

1.檢查服務器端口8081是否開啟監聽2.檢查路由項是否被防火墻攔截方法 1&#xff1a;使用 netsh查看防火墻規則?netsh advfirewall firewall show rule nameall dirout | findstr "8081"如果無輸出&#xff0c;說明防火墻未針對該端口設置規則&#xff08;可能默認攔…

Linux 內存管理(2):了解內存回收機制

目錄一、透明大頁1.1 原理1.2 透明大頁的三大優勢1.3 透明大頁控制接口詳解1.4 使用場景與最佳實踐1.5 問題排查與監控1.6 與傳統大頁的對比二、Linux伙伴系統水位機制詳解2.1 三種核心水位詳解2.2 水位在伙伴系統中的實現2.3 水位觸發機制的實際行為2.4 水位關鍵操作接口2.5 水…

前端學習7:CSS過渡與動畫--補間動畫 (Transition) vs 關鍵幀動畫 (Animation)

一、補間動畫&#xff08;Tween Animation&#xff09;vs 關鍵幀動畫&#xff08;Keyframe Animation&#xff09;概念對比表&#xff1a;補間動畫 (Transition)關鍵幀動畫 (Animation)定義元素從初始狀態到結束狀態的過渡效果通過定義多個關鍵幀控制動畫的中間狀態觸發方式需要…

PyTorch 損失函數詳解:從理論到實踐

目錄 一、損失函數的基本概念 二、常用損失函數及實現 1. 均方誤差損失&#xff08;MSELoss&#xff09; 2. 平均絕對誤差損失&#xff08;L1Loss/MAELoss&#xff09; 3. 交叉熵損失&#xff08;CrossEntropyLoss&#xff09; 4. 二元交叉熵損失&#xff08;BCELoss&…

MinIO深度解析:從核心特性到Spring Boot實戰集成

在當今數據爆炸的時代&#xff0c;海量非結構化數據的存儲與管理成為企業級應用的關鍵挑戰。傳統文件系統在TB級數據面前捉襟見肘&#xff0c;而昂貴的云存儲服務又讓中小企業望而卻步。MinIO作為一款開源高性能對象存儲解決方案&#xff0c;正以其獨特的技術優勢成為開發者的首…

騰訊云服務上下載docker以及使用Rabbitmq的流程

執行以下命令&#xff0c;添加 Docker 軟件源并配置為騰訊云源。sudo yum-config-manager --add-repohttps://mirrors.cloud.tencent.com/docker-ce/linux/centos/docker-ce.repo sudo sed -i "s/download.docker.com/mirrors.tencentyun.com\/docker-ce/g" /etc/yu…

UE5 一些關于過場動畫sequencer,軌道track的一些Python操作

刪除多余的軌道 import unreal def execute():movie_scene_actors []sequence_assets []data 0.0# 獲取編輯器實用工具庫lib unreal.EditorUtilityLibrary()selected_assets lib.get_selected_assets()for asset in selected_assets:if asset.get_class() unreal.LevelS…

前端性能優化“核武器”:新一代圖片格式(AVIF/WebP)與自動化優化流程實戰

前端性能優化“核武器”&#xff1a;新一代圖片格式(AVIF/WebP)與自動化優化流程實戰 當你的頁面加載時間超過3秒時&#xff0c;用戶的跳出率會飆升到40%以上。而在所有的前端性能優化手段中&#xff0c;圖片優化無疑是投入產出比最高的一環。一張未經優化的巨大圖片&#xff0…

單元測試學習+AI輔助單測

標題單元測試衡量指標具體測試1、Resource2、MockBean3、Test4、Test模板5、單測示例H2數據庫JSON1、使用方式AI輔助單測使用方法單元測試 單元測試一般指程序員在寫好代碼后&#xff0c;提交測試前&#xff0c;需要驗證自己的代碼是否可以正常工作&#xff0c;同時將自己的代…

Spring Cloud Gateway與Envoy Sidecar在微服務請求路由中的架構設計分享

Spring Cloud Gateway與Envoy Sidecar在微服務請求路由中的架構設計分享 在現代微服務架構中&#xff0c;請求路由層承擔著流量分發、安全鑒權、流量控制等多重職責。傳統的單一網關方案往往面臨可擴展性和可維護性挑戰。本文將從真實生產環境出發&#xff0c;分享如何結合Spri…

GitHub Pages+Jekyll 靜態網站搭建(二)

GitHub PagesJekyll 靜態網站搭建&#xff08;二&#xff09;GitHub PagesJekyll 靜態網站搭建&#xff08;二內容簡介搭建模板網站部署工作流程GitHub PagesJekyll 靜態網站搭建&#xff08;二 內容簡介 &#x1f6a9; Tech Contents 該文主要涉及Jekyll主題的下載與使用。Gi…

Django 實戰:I18N 國際化與本地化配置、翻譯與切換一步到位

文章目錄一、國際化與本地化介紹定義相關概念二、安裝配置安裝 gettext配置 settings.py三、使用國際化視圖中使用序列化器和模型中使用四、本地化操作創建或更新消息文件消息文件說明編譯消息文件五、項目實戰一、國際化與本地化介紹 定義 國際化和本地化的目標&#xff0c;…

通過國內扣子(Coze)搭建智能體并接入discord機器人

國內的扣子是無法直接授權給discord的&#xff0c;但是用國外的coze的話&#xff0c;大模型調用太貴&#xff0c;如果想要接入國外的平臺&#xff0c;那就需要通過調用API來實現。 1.搭建智能體&#xff08;以工作流模式為例&#xff09; 首先&#xff0c;我們需要在扣子平臺…

【辦公類-107-02】20250719視頻MP4轉gif(削減MB)

背景需求 最近在寫第五屆智慧項目結題(一共3篇)寫的昏天黑地,日以繼夜。 我自己《基于“AI技術”的幼兒園教學資源開發和運用》提到了AI繪畫、AI視頻和AI編程。 為了更好的展示AI編程的狀態,我在WORD里面插入了MP4轉gif的動圖。 【教學類-75-04】20241023世界名畫-《蒙…

一文講清楚React的render優化,包括shouldComponentUpdate、PureComponent和memo

文章目錄一文講清楚React的render優化&#xff0c;包括shouldComponentUpdate、PureComponent和memo1. React的渲染render機制2. shouldComponentUpdate2.1 先上單組件渲染&#xff0c;驗證state變化2.2 上父子組件&#xff0c;驗證props2. PureComponent2.1 單組件驗證state2.…

物聯網iot、mqtt協議與華為云平臺的綜合實踐(萬字0基礎保姆級教程)

本學期的物聯網技術與應用課程&#xff0c;其結課設計內容包含&#xff1a;mqtt、華為云、PyQT5和MySQL等結合使用&#xff0c;完成了從華為云配置產品信息以及轉發規則&#xff0c;到mqtt命令轉發&#xff0c;再到python編寫邏輯代碼實現相關功能&#xff0c;最后用PyQT5實現面…

使用IntelliJ IDEA和Maven搭建SpringBoot集成Fastjson項目

使用IntelliJ IDEA和Maven搭建SpringBoot集成Fastjson項目 下面我將詳細介紹如何在IntelliJ IDEA中使用Maven搭建一個集成Fastjson的SpringBoot項目&#xff0c;包含完整的環境配置和代碼實現。 一、環境準備 軟件要求 IntelliJ IDEA 2021.x或更高版本JDK 1.8或更高版本&#x…

Java從入門到精通!第九天, 重點!(集合(一))

十一、集合1. 為什么要使用集合(1) 數組存在的弊端1) 數組在初始化之后&#xff0c;長度就不能改變&#xff0c;不方便擴展。2) 數組中提供的屬性和方法比較少&#xff0c;不便于進行添加、刪除、修改等操作&#xff0c;并且效率不高&#xff0c;同時無法直接存儲元素的個數。3…

為什么使用時序數據庫

為什么使用時序數據庫&#xff1f; 時序數據庫&#xff08;Time-Series Database, TSDB&#xff09;是專為時間序列數據優化的數據庫&#xff0c;相比傳統關系型數據庫&#xff08;如MySQL&#xff09;或NoSQL數據庫&#xff08;如MongoDB&#xff09;&#xff0c;它在以下方面…

計算機網絡:(十一)多協議標記交換 MPLS

計算機網絡&#xff1a;&#xff08;十一&#xff09;多協議標記交換 MPLS前言一、傳統網絡的問題二、MPLS&#xff1a;給數據包貼個“標簽”三、MPLS的工作流程1. 入站2. 中間3. 出站四、MPLS的能力前言 前面我們講解了計算機網絡中網絡層的相關知識&#xff0c;包括網絡層轉發…