Selenium遍历带随机数后缀的分页站点返回空白页问题求解
问题说明
目标爬取站点采用分页结构,但无法通过直接遍历页码的方式访问全部分页:每个分页URL末尾附带服务端生成的数字校验后缀,仅替换页码占位符发起请求会返回空白页面。
站点分页URL示例:
- 第二页真实地址:
https://market.bisnis.com/bursa-saham/2/20220621181040 - 通用URL结构:
https://market.bisnis.com/bursa-saham/{页码}/{动态校验后缀}
原有问题代码
options = Options() options.add_argument("start-maximized") options.add_argument('--no-sandbox') element_list = [] for page in range(1,3, 1): page_url = "https://market.bisnis.com/bursa-saham/" + str(page) driver = webdriver.Chrome("C:/Users/krish/Desktop/chromedriver_win32/chromedriver.exe", chrome_options=options,) driver.get(page_url) title = driver.find_elements(By.TAG_NAME, 'h2') for i in range(len(title)): element_list.append([title[i].text]) with xlsxwriter.Workbook('result2.xlsx') as workbook: worksheet = workbook.add_worksheet() for row_num, data in enumerate(element_list): worksheet.write_row(row_num, 0, data) driver.close()
问题根因
- URL末尾的数字串不是随机无效值,是服务端用来校验分页请求合法性的标识(一般是分页生成时间戳或锚点参数),缺失该参数的请求会被反爬规则拦截,直接返回空白页
- 浏览器驱动初始化放在循环内部,每爬一页就新开一个Chrome实例,资源占用极高,还容易触发站点反爬
- 没有设置页面加载等待,DOM未渲染完成就提取元素,容易拿到空值
- 仅调用
close()方法关闭浏览器,残留进程无法被完全清理
修复方案
不需要逆向校验后缀的生成规则,直接从当前已加载页面的分页导航里提取下一页的真实跳转地址即可,具体实现逻辑:
- 初始化一次浏览器实例,从第一页地址开始访问
- 等页面元素加载完成后提取当前页的所有目标标题
- 定位分页区的「下一页」按钮,读取它的
href属性拿到带合法后缀的下一页地址 - 循环执行爬取、提取下一页地址的操作,直到到达指定爬取页数、或找不到下一页按钮时终止
- 爬取完成后统一退出浏览器,清理进程
修正后的可运行代码:
from selenium.webdriver.chrome.options import Options from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium import webdriver import xlsxwriter options = Options() options.add_argument("start-maximized") options.add_argument('--no-sandbox') options.add_argument('--disable-dev-shm-usage') # 仅初始化一次浏览器,不要放在循环内反复新建 driver = webdriver.Chrome(executable_path="C:/Users/krish/Desktop/chromedriver_win32/chromedriver.exe", options=options) element_list = [] # 初始第一页地址 current_url = "https://market.bisnis.com/bursa-saham/1" # 配置需要爬取的最大页码 max_crawl_page = 3 for page_num in range(1, max_crawl_page + 1): driver.get(current_url) # 显式等待h2标签加载完成,避免硬等或拿空值 WebDriverWait(driver, 10).until( EC.presence_of_all_elements_located((By.TAG_NAME, 'h2')) ) title_list = driver.find_elements(By.TAG_NAME, 'h2') for title in title_list: t = title.text.strip() if t: element_list.append([t]) # 未到最后一页时提前提取下一页真实地址 if page_num < max_crawl_page: try: # 下一页按钮选择器可根据实际DOM结构调整 next_page_btn = driver.find_element(By.CSS_SELECTOR, 'ul.pagination li.next a') current_url = next_page_btn.get_attribute('href') except: print(f"第{page_num}页后无更多分页,提前终止爬取") break # 全部爬取完成后退出浏览器,清理所有进程 driver.quit() # 写入结果到Excel with xlsxwriter.Workbook('result2.xlsx') as workbook: worksheet = workbook.add_worksheet() for row_num, row_data in enumerate(element_list): worksheet.write_row(row_num, 0, row_data)
注意事项
- 如果代码里的下一页按钮CSS选择器匹配不到元素,可以在浏览器中右键点击下一页按钮,选择「检查」查看它的实际标签属性,调整对应选择器即可
- 如果需要爬取更多页数,直接修改
max_crawl_page的数值就行,不需要改动其他逻辑 - 显式等待默认超时时间是10秒,如果网络环境差可以适当调大数值
内容的提问来源于stack exchange,提问作者krsnbcd
相关产品推荐
相关产品推荐

