雪之下路漫漫 发表于 2024-12-1 13:06:33

关于selenium爬虫的问题

本帖最后由 雪之下路漫漫 于 2024-12-1 13:19 编辑

纯小白,我用selenium写了个爬猎聘网页的代码。但是很怪的是,我循环提取一个个工作的相关内容,但是不知道到哪一个就停下来报错了。比如这次我可能运行到第五个工作就会报错,下次可能到第七个工作报错。明明能运行,但莫名的会停止在某一个工作上。问了gpt,但是也只有很模糊的回答,可能也是问题本身就很模糊。。如果有大佬解答,非常感谢!

小甲鱼的二师兄 发表于 2024-12-1 13:06:34

from selenium import webdriver
from selenium.webdriver.common.by import By
import time

from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

options = webdriver.ChromeOptions()
driver = webdriver.Chrome(options=options)
wait = WebDriverWait(driver, 10)

# 打开猎聘网
url = "https://www.liepin.com/"
driver.get(url)

# 搜索 '会计'
search_input = wait.until(EC.presence_of_element_located((By.XPATH, '//input[@class="jsx-1374046090"]')))
search_input.send_keys('会计')
search_button = driver.find_element(By.XPATH, '//span[@class="jsx-1374046090 search-btn"]')
search_button.click()

# 等待搜索结果页面加载
wait.until(EC.presence_of_element_located((By.XPATH, '//div[@class="job-list-box"]')))

print(driver.current_url)

# 收集所有职位链接和公司名称
job_elements = driver.find_elements(By.XPATH, '//div[@class="job-list-box"]/div')
job_links = []
company_names = []
for index, element in enumerate(job_elements):
    try:
      # 获取公司名称
      company_elem = element.find_element(By.XPATH, './/span[@class="company-name ellipsis-1"]')
      company_name = company_elem.text
      # 获取职位链接
      job_link_elem = element.find_element(By.XPATH, './/a')
      job_link = job_link_elem.get_attribute('href')
      job_links.append(job_link)
      company_names.append(company_name)
      print(f"已收集职位 #{index + 1},公司:{company_name}")
    except Exception as e:
      print(f"收集职位 #{index + 1} 出错:{e}")

# 逐一访问职位链接并提取内容
for index, (job_link, company_name) in enumerate(zip(job_links, company_names)):
    try:
      # 打开职位链接
      driver.execute_script("window.open(arguments);", job_link)
      driver.switch_to.window(driver.window_handles[-1])

      # 等待职位详情内容加载
      content = wait.until(EC.presence_of_element_located((By.XPATH, '//dd[@data-selector="job-intro-content"]')))
      print(f"正在处理职位 #{index + 1},公司:{company_name}")
      print("职位内容:", content.text)

      # 关闭职位详情页
      driver.close()
      driver.switch_to.window(driver.window_handles)

    except Exception as e:
      print(f"处理职位 #{index + 1} 出错:{e}")
      driver.close()
      driver.switch_to.window(driver.window_handles)

    finally:
      time.sleep(2)# 等待片刻再处理下一个职位

# 保持浏览器打开用于检查
time.sleep(1000)

小甲鱼的二师兄 发表于 2024-12-1 14:59:01

这个试试?

雪之下路漫漫 发表于 2024-12-2 03:01:16

小甲鱼的二师兄 发表于 2024-12-1 14:59
这个试试?

感谢小甲鱼!确实可以了。但是还是想请教您两个问题
1、为什么这种driver.execute_script("window.open(arguments);", job_link)的方式打开链接,取内容,然后关闭网页的循环就可以一直执行下去。但我那种纯粹模拟鼠标行为的点开按钮,再关闭这样循环的方式就容易出问题呢?是有什么具体的原因吗,还是纯粹模拟鼠标行为的方式特性如此,就是更容易出问题呢?
因为我之前的代码就是明明能运行,但是不知道会在某一个循环元素那运行失败,就很奇怪。。要不就每一个元素都循环失败,要不就都成功嘛。。
2、还有就是刚刚在运行这个新代码的时候,会跳出来短信验证的异常页面,想知道有什么方式可以规避这种异常验证嘛。我已经设置了10秒的睡眠间隔了,还是会有。。因为代码编程只是我的兴趣爱好,所以学不来逆向js,只能用这种selenium的方式爬虫。如果有什么好方法能避免异常验证或者有课件的话,希望能告诉我,非常感谢!!

小甲鱼的二师兄 发表于 2024-12-7 13:40:12

雪之下路漫漫 发表于 2024-12-2 03:01
感谢小甲鱼!确实可以了。但是还是想请教您两个问题
1、为什么这种driver.execute_script("window.open( ...

driver.execute_script("window.open(arguments);", job_link) 是通过执行 JavaScript 直接在浏览器中打开一个新的标签页,这是一种高效且相对低干扰的方式。与模拟鼠标点击行为相比,它的操作逻辑更直接,绕过了很多与页面交互相关的复杂性。

模拟鼠标行为(如 .click() 或 ActionChains)依赖于页面元素的可见性、可交互性、位置计算等因素。页面动态加载、CSS 动画、JavaScript 事件绑定等可能导致元素在某些时间点不可点击或错位(即使元素看起来已经加载了)。这种复杂性增加了失败的可能。

小甲鱼的二师兄 发表于 2024-12-7 13:43:43

雪之下路漫漫 发表于 2024-12-2 03:01
感谢小甲鱼!确实可以了。但是还是想请教您两个问题
1、为什么这种driver.execute_script("window.open( ...

关于第二个问题,只要确保访问效率不对服务器产生负面影响,一般也不会拦截屏蔽你的爬虫。

可以考虑以下优化:

1. 模拟更真实的用户行为(随机延迟、滚动页面、鼠标移动)。

2. 使用代理 IP 和修改浏览器标识。

3. 保存并加载登录后的 Cookies。

页: [1]
查看完整版本: 关于selenium爬虫的问题