Selenium网页爬虫代码解析 | AI生成和翻译

Home 2025.10

代码中 Selenium API 使用说明

这段 Python 脚本使用 Selenium WebDriver 库来自动化网页浏览器(特别是 Chrome),以便与网站(很可能是位于 https://xxdata.com/index.aspx 的数据/贸易门户网站)进行交互。其目标似乎是网络爬取:登录、搜索贸易/订单数据(使用如 ‘8449’ 的 HS 编码)、浏览分页结果、点击查看详情、从 HTML 表格中提取结构化数据,并将其存储到 SQLite 数据库 (data.db) 中。

这里使用 Selenium 是为了浏览器自动化,使脚本能够模拟人类的交互行为,如输入、点击、滚动和等待页面加载——这对于简单的 HTTP 请求(例如,由于 JavaScript 繁重的页面、iframe 或动态内容)来说是困难或不可能实现的。它能处理动态网页元素、会话和多窗口/iframe 切换,这些在现代网络应用中很常见。

我将逐节进行分解,重点介绍关键的 Selenium API、它们的用途以及它们是如何被使用的。注意:代码中的某些方法(例如 find_element_by_css_selector)来自旧版 Selenium(4.0 之前),并且已弃用。在现代 Selenium(4+)中,您应使用 find_element(By.CSS_SELECTOR, ...),但其功能是相同的。该脚本还导入了用于等待、异常处理和元素操作的必要模块。

1. 导入和设置(Selenium 初始化)

   from selenium import webdriver
   from selenium.webdriver.chrome.webdriver import WebDriver
   from selenium.webdriver.common.keys import Keys
   from selenium.common.exceptions import TimeoutException, ElementClickInterceptedException, StaleElementReferenceException
   from selenium.webdriver.support.ui import WebDriverWait
   from selenium.webdriver.support import expected_conditions as EC
   from selenium.webdriver.common.by import By
   from selenium.webdriver.remote.webelement import WebElement

run() 函数中:

   options = webdriver.ChromeOptions()
   options.add_argument("--start-maximized")  # 以全屏模式打开浏览器。
   options.add_argument('--log-level=3')      # 抑制控制台日志输出,使输出更清晰。
   browser: WebDriver = webdriver.Chrome(executable_path="./chromedriver", options=options)
   browser.get('https://xxdata.com/index.aspx')

2. 登录过程

   input_username = browser.find_element_by_css_selector('input[name=username]')
   input_username.send_keys('name')
   input_password = browser.find_element_by_css_selector('input[name=password]')
   input_password.send_keys('password')
   btn_login = browser.find_element_by_css_selector('div.login-check')
   btn_login.click()

登录后:

   wait_element(browser, 'div.dsh_01')

3. 导航和搜索

   trade_div = browser.find_element_by_css_selector('div.dsh_01')
   trade_div.click()
   wait_element(browser, 'a.teq_icon')
   teq = browser.find_element_by_css_selector('a.teq_icon')
   teq.click()
   wait_element(browser, 'div.panel-body')
   iframe = browser.find_element_by_css_selector('div.panel-body > iframe')
   iframe_id = iframe.get_attribute('id')
   browser.switch_to.frame(iframe_id)

搜索过程:

   input_search = browser.find_element_by_id('_easyui_textbox_input7')  # 使用 ID 定位器。
   input_search.send_keys('8449')
   time.sleep(10)
   enter = browser.find_element_by_css_selector('a#btnOk > div.enter-bt')
   enter.click()

4. 分页和结果处理

   result_count_span = browser.find_element_by_css_selector('span#ResultCount')
   page = math.ceil(int(result_count_span.text) / 20)  # 计算总页数(每页 20 条结果)。
   skip = 0
   page = page - skip

   for p in range(page):
       input_page = browser.find_element_by_css_selector('input.laypage_skip')
       input_page.send_keys(str(p + skip + 1))
       btn_confirm = browser.find_element_by_css_selector('button.laypage_btn')
       btn_confirm.click()
       time.sleep(2)

       locates = browser.find_elements_by_css_selector('div.rownumber-bt')  # 多个元素。
       print('page ' + str(p) + ' size: ' + str(len(locates)))
       for locate in locates:
           browser.execute_script("arguments[0].scrollIntoView();", locate)  # JavaScript 滚动。
           time.sleep(1)
           browser.find_element_by_tag_name('html').send_keys(Keys.PAGE_UP)  # 键盘滚动。
           time.sleep(1)
           try:
               locate.click()
           except ElementClickInterceptedException:
               print('ElementClickInterceptedException')
               continue
           except StaleElementReferenceException:
               print('StaleElementReferenceException')
               continue
           # ... (后续更多代码)

5. 窗口/Iframe 切换和数据提取

从循环继续:

   time.sleep(1)
   browser.switch_to.window(browser.window_handles[1])  # 切换到新标签页/窗口。
   wait_element(browser, 'div#content')
   try:
       save_page(browser)
   except IndexError:
       print('IndexError')
       continue
   browser.close()  # 关闭详情窗口。
   browser.switch_to.window(browser.window_handles[0])  # 返回主窗口。
   browser.switch_to.frame(iframe_id)  # 返回 iframe 上下文。

6. save_page(browser: WebDriver) 函数中的数据提取

这是核心的爬取逻辑:

   ts = browser.find_elements_by_css_selector('table')  # 页面上的所有表格。
   t0 = ts[0]
   tds0 = t0.find_elements_by_tag_name('td')  # 第一个表格中的 TD 单元格。
   order_number = tds0[2].text  # 从特定单元格提取文本。
   # ... (对其他表格 t1, t2 等类似操作)

条件逻辑根据表格索引提取字段,如 order_numberimporterexporter 等——假设布局是固定的。

7. 等待和错误处理(wait_element 函数)

   def wait_element(browser, css):
       timeout = 30
       try:
           element_present = EC.presence_of_element_located((By.CSS_SELECTOR, css))
           WebDriverWait(browser, timeout).until(element_present)
       except TimeoutException:
           print('Timed out waiting for page to load')

8. 清理

   time.sleep(1000)  # 长暂停(用于调试?)。
   browser.quit()    # 关闭浏览器并结束会话。

Selenium 的整体作用

如果您对特定部分、代码现代化或调试有疑问,请告诉我!


Back

x-ai/grok-4-fast

Donate