姚梨素 发表于 3 天前

基于selenium的网页自动搜索

第一节

通过简单的百度网页打开学习selenium库的基本功能。
1 from selenium import webdriver
2 from selenium.webdriver.chrome.service import Service
3 from selenium.webdriver.chrome.options import Options
4 from selenium.webdriver.common.by import By
5 from selenium.webdriver.support.ui import WebDriverWait
6 from selenium.webdriver.support import expected_conditions as EC
7 import time
8
9 from selenium.webdriver.common.keys import Keys
10
11 # 配置 ChromeDriver 路径,替换为你的 ChromeDriver 路径,你也可以将chromedriver拖入文件根目录,使用'./chromedriver.exe'路径。
12 chrome_driver_path = 'E:/Git_repo/VSCode_tmp/autopython/chromedriver-win64/chromedriver.exe'# 替换为你的 ChromeDriver 路径
13
14 # 初始化 ChromeDriver Service
15 service = Service(chrome_driver_path)
16 # 打开浏览器时的相关配置,可以根据需求进行打开和关闭
17 options = Options()
18 options.add_argument("--start-maximized")# 启动时最大化窗口
19 options.add_argument("--disable-blink-features=AutomationControlled")# 使浏览器不显示自动化控制的信息
20 # options.add_argument("--disable-gpu")# 禁用GPU硬件加速
21 options.add_argument("--disable-infobars")# 隐藏信息栏
22 # options.add_argument("--disable-extensions")# 禁用所有扩展程序
23 # options.add_argument("--disable-popup-blocking")# 禁用弹出窗口拦截
24 # options.add_argument("--incognito")# 启动无痕模式
25 # options.add_argument("--no-sandbox")# 关闭沙盒模式(提高性能)
26 # options.add_argument("--disable-dev-shm-usage")# 使用/dev/shm分区以避免共享内存问题
27 # options.add_argument("--remote-debugging-port=9222")# 启用远程调试端口
28 options.add_experimental_option("excludeSwitches", ["enable-automation"])
29 options.add_experimental_option("useAutomationExtension", False)
30
31
32 # 初始化 WebDriver,并传入 ChromeDriver Service
33 driver = webdriver.Chrome(service=service, options=options)
34 # # 防反爬:隐藏 webdriver 特征
35 # driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => false});")
36
37 try:
38   # 打开百度搜索首页
39   url = "https://www.baidu.com"
40   driver.get(url)
41   # 显式等待,直到搜索框出现
42   wait = WebDriverWait(driver, 10)
43   # 通过Xpath表达式获取到百度输入框的html元素,方法也提供By.ID和By.CLASS_NAME的方法,用户可自动尝试
44   search_box = wait.until(EC.presence_of_element_located((By.XPATH, "//*[@id='chat-textarea']")))
45   # 输入搜索关键词
46   search_box.send_keys("原神"+ Keys.RETURN)
47   # 模拟按下回车键进行搜索
48   #search_box.submit()
49   # 等待搜索结果加载完成
50   wait.until(EC.presence_of_element_located((By.XPATH, "//div[@id='content_left']")))
51   # 打印搜索结果的标题
52   print(driver.title)
53   # 延时五秒展示结果
54   time.sleep(5)
55
56 finally:
57   # 关闭 WebDriver
58   driver.quit()代码主要分为五大块,第一块为导入selenium库驱动网页所需要的包和驱动chrome浏览器的chrome_driver;第二块为初始化ChromeDriver Service主要为控制如何打开浏览器;第三块为初始化 WebDriver,并传入 ChromeDriver Service;第五块为具体打开网页和处理网页按钮的方法,这里使用了XPATH方式寻找网页元素。
第二节

要想实现网页自动化登录最简单的方法是使用cookie方式登录,通过保存之前登录网页的cookie实现网页的自动化登录,而且还可以避免使用自动化工具打开浏览器无法保存登录信息的问题。
1 from selenium import webdriver
2 from selenium.webdriver.chrome.service import Service
3 from selenium.webdriver.chrome.options import Options
4 import os
5 import json
6 import time
7
8 # 配置 ChromeDriver 路径,替换为你的 ChromeDriver 路径,你也可以将chromedriver拖入文件根目录,使用'./chromedriver.exe'路径。
9 chrome_driver_path = 'E:/Git_repo/VSCode_tmp/autopython/chromedriver-win64/chromedriver.exe'# 替换为你的 ChromeDriver 路径
10
11 # 初始化 ChromeDriver Service
12 service = Service(chrome_driver_path)
13 options = Options()
14 options.add_argument("--disable-blink-features=AutomationControlled")# 使浏览器不显示自动化控制的信息
15
16 # 初始化 WebDriver,并传入 ChromeDriver Service
17 driver = webdriver.Chrome(service=service, options=options)
18
19 try:
20   # 打开小红书首页
21   url = "https://www.xiaohongshu.com"
22   driver.get(url)
23   time.sleep(40)# 等待页面加载完成
24
25   # 获取 cookies
26   cookies = driver.get_cookies()
27
28   # 打印当前工作目录
29   print("Current working directory: ", os.getcwd())
30
31
32   # 将 cookies 保存到文件
33   with open("cookies.json", "w") as f:
34         json.dump(cookies, f)
35   print("Cookies have been saved to cookies.json")
36 finally:
37   # 关闭 WebDriver
38   driver.quit()上面程序通过手动登录网页而后再保存网页cookie用于之后的自动化登录。
第三节

通过上面的保存的cookie,编写程序实现网页自动登录并实现指定内容搜索。
1 from selenium import webdriver
2 from selenium.webdriver.chrome.service import Service
3 from selenium.webdriver.chrome.options import Options
4 from selenium.webdriver.common.by import By
5 from selenium.webdriver.support.ui import WebDriverWait
6 from selenium.webdriver.support import expected_conditions as EC
7
8 from selenium.common.exceptions import NoSuchElementException
9 import random
10 import os
11 import time
12 import json
13
14
15 from selenium.webdriver.common.keys import Keys
16
17 # 配置 ChromeDriver 路径,替换为你的 ChromeDriver 路径,你也可以将chromedriver拖入文件根目录,使用'./chromedriver.exe'路径。
18 chrome_driver_path = 'E:/Git_repo/VSCode_tmp/autopython/chromedriver-win64/chromedriver.exe'# 替换为你的 ChromeDriver 路径
19
20 # 初始化 ChromeDriver Service
21 service = Service(chrome_driver_path)
22 # 打开浏览器时的相关配置,可以根据需求进行打开和关闭
23 options = Options()
24 options.add_argument("--start-maximized")# 启动时最大化窗口
25 options.add_argument("--disable-blink-features=AutomationControlled")# 使浏览器不显示自动化控制的信息
26 # options.add_argument("--disable-gpu")# 禁用GPU硬件加速
27 options.add_argument("--disable-infobars")# 隐藏信息栏
28 # options.add_argument("--disable-extensions")# 禁用所有扩展程序
29 # options.add_argument("--disable-popup-blocking")# 禁用弹出窗口拦截
30 # options.add_argument("--incognito")# 启动无痕模式
31 # options.add_argument("--no-sandbox")# 关闭沙盒模式(提高性能)
32 # options.add_argument("--disable-dev-shm-usage")# 使用/dev/shm分区以避免共享内存问题
33 # options.add_argument("--remote-debugging-port=9222")# 启用远程调试端口
34 options.add_experimental_option("excludeSwitches", ["enable-automation"])
35 options.add_experimental_option("useAutomationExtension", False)
36
37
38 MAX_ITEMS_BEFORE_WRITING = 5# 每收集 5 条数据就写入一次文件
39
40 def write_to_file(collected_items):
41   print("当前工作目录:", os.getcwd())
42   # 追加写入文件的逻辑
43   with open('result.json', 'a', encoding='utf-8') as file:
44         json_data =
45         file.write('\n'.join(json_data) + '\n')
46   print("Results saved successfully.")
47
48 #随机延时函数,用来模拟动作比较快的点击操作
49 def random_delay(time_start, time_end):
50   delay = random.uniform(time_start, time_end)
51   time.sleep(delay)
52
53 def scroll_and_collect(driver, num_items):
54   collected_items = []
55   collected_count = 0
56   result_count = 0
57   while result_count < num_items:
58         # 获取了页面上的所有选项卡
59         items = driver.find_elements(By.XPATH, "//section[@class='note-item']")
60         # 遍历获取的列表,分析里面的元素
61         for item in items:
62             try:
63               # 找到元素里封面、标题、作者昵称、作者头像等元素
64               cover = item.find_element(By.XPATH, ".//a[@class='cover mask ld']/img").get_attribute("src")
65               title = item.find_element(By.XPATH, ".//a[@class='title']//span").text
66               author_avatar = item.find_element(By.XPATH, ".//a[@class='author']//img[@class='author-avatar']").get_attribute("src")
67               author_name = item.find_element(By.XPATH, ".//a[@class='author']//span").text
68
69               # 存储获取的结果
70               collected_items.append({
71                     "cover": cover,
72                     "title": title,
73                     "author_avatar": author_avatar,
74                     "author_name": author_name
75               })
76               result_count += 1
77               collected_count += 1
78               # 写入文件
79               if collected_count >= MAX_ITEMS_BEFORE_WRITING:
80                     write_to_file(collected_items)
81                     collected_items = []# 清空已收集的项
82                     collected_count = 0# 重置计数器
83             except NoSuchElementException:
84               continue
85         # 翻页
86         driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
87         random_delay(4, 8)# 等待页面加载新的内容
88
89         # 等待新内容加载的逻辑
90         try:
91             WebDriverWait(driver, 10).until(
92               EC.presence_of_element_located((By.XPATH, "//section[@class='note-item']"))
93             )
94         except NoSuchElementException:
95             break
96         # 最后一次写入剩余的项
97   if collected_count > 0:
98         write_to_file(collected_items)
99   return collected_items
100
101 # 初始化 WebDriver,并传入 ChromeDriver Service
102 driver = webdriver.Chrome(service=service, options=options)
103 # # 防反爬:隐藏 webdriver 特征
104 # driver.execute_script("Object.defineProperty(navigator, 'webdriver', {get: () => false});")
105
106 try:
107   # 打开小红书首页
108   url = "https://www.xiaohongshu.com"
109   driver.get(url)
110
111   #time.sleep(4)# 等待页面加载完成,后面改成显式等待
112   # 显式等待,直到二维码登录出现
113   wait = WebDriverWait(driver, 5)
114   try:
115         # 通过Xpath表达式获取到XHS登录框的html元素,判断是否可以登录
116         ## 此处需要重新确认XPATH元素,修改不使用直接复制F12值
117         search_box = wait.until(EC.presence_of_element_located((By.XPATH, "//*[@id='app']/div/div/div/div")))
118         print("成功等待登录界面")
119   except Exception as e:
120         print(f"等待登录界面超时,错误信息:{e}")
121
122   #读取之前的cookies
123   with open("cookies.json", "r") as f:
124         cookies = json.load(f)
125   # 添加每个cookie到浏览器
126   for cookie in cookies:
127         driver.add_cookie(cookie)
128   
129   #刷新页面
130   driver.refresh()
131
132   wait = WebDriverWait(driver, 3)
133   # 等待登录按钮 **消失**(最多 3 秒),也可以判断cookie是否有效
134   try:
135         wait.until(EC.invisibility_of_element_located((By.XPATH, '//*[@id="login-btn"]')))
136         print("成功登录小红书")
137   except Exception as e:
138         print(f"登录小红书失败,错误信息:{e}")
139
140   time.sleep(5)
141      # 显式等待,直到搜索框出现
142   wait = WebDriverWait(driver, 10)
143   search_box = wait.until(EC.presence_of_element_located((By.XPATH, "//input[@placeholder='搜索小红书']")))
144   search_box.send_keys("漫展")
145   time.sleep(5)
146   search_button = wait.until(EC.element_to_be_clickable((By.XPATH, "//div[@class='input-button']")))
147   search_button.click()
148   time.sleep(5)
149   wait.until(EC.presence_of_element_located((By.XPATH, "//section[@class='note-item']")))
150   time.sleep(5)
151
152   num_items = 100
153   scroll_and_collect(driver, num_items)
154
155   '''##单次测试代码
156
157   items = driver.find_elements(By.XPATH, "//section[@class='note-item']")
158   print(f"找到 {len(items)} 个笔记项")
159   print(items)
160   collected_items = []
161   collected_count = 0
162   result_count = 0
163   for item in items:
164         try:
165             # 找到元素里封面、标题、作者昵称、作者头像等元素
166             cover = item.find_element(By.XPATH, ".//a[@class='cover mask ld']/img").get_attribute("src")
167             title = item.find_element(By.XPATH, ".//a[@class='title']//span").text
168             author_avatar = item.find_element(By.XPATH, ".//a[@class='author']//img[@class='author-avatar']").get_attribute("src")
169             author_name = item.find_element(By.XPATH, ".//a[@class='author']//span").text
170
171             # 存储获取的结果
172             collected_items.append({
173               "cover": cover,
174               "title": title,
175               "author_avatar": author_avatar,
176               "author_name": author_name
177             })
178             result_count += 1
179             collected_count += 1
180             # 写入文件
181             if collected_count >= MAX_ITEMS_BEFORE_WRITING:
182               write_to_file(collected_items)
183               collected_items = []# 清空已收集的项
184               collected_count = 0# 重置计数器
185         except NoSuchElementException:
186             continue
187         
188         '''
189   # 延时几秒以便查看搜索结果
190   time.sleep(60)
191
192 finally:
193   # 关闭 WebDriver
194   driver.quit()构造登录环境和初始化WebDriver与第一节一致,这里不重复,这里主要讲代码打开网页之后的操作。整个执行部分分为两块,一块是自动登录,一块是网页指定内容搜索。
自动登录主要分为三步。第一步,进入网页后检测是否有登录二维码,如果有则认为网页加载完成可以进行登录;第二步,通过导入之前保存的cookie,刷新完成网页的自动登录;第三步,通过检测网页是否存在登录按钮,判断登录操作是否成功,如果没有则认为成功。
网页指定内容搜索主要是通过找到搜索框并将指定文字内容写入实现功能。根据网页的特点保存网页元素,并在每个元素内保存指定的字段内容用于其他。
 
总结

在完成这些程序之前我根本没有网页自动化的任何知识,通过阅读前人的教程和询问AI居然可以实现基本的功能,这让我再一次认识到AI能力的强大,至少在python自动化上已经超过大多数人了!!!
 
参考链接

Python使用selenium库实现网页自动化登陆以及数据抓取(爬虫)教程 - 云霄雨霁 - 博客园
30分钟上手Web自动化测试:Python+Selenium零基础实战指南 - xiaodi888 - 博客园
Selenium 教程 | 菜鸟教程
入门指南 | Selenium
通义AI助手
 

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: 基于selenium的网页自动搜索