RSelenium爬取Fortune公司页员工数 定位与批量爬取报错排查
爬取Fortune公司页面员工数问题排查
初始单页爬取失败原因
- 选择器语法混用:SelectorGadget生成的
info__row--7f9lE:nth-child(13) .info__value--2AHH7是CSS选择器,你直接将其作为XPath的class属性值写入查询语句,语法完全不成立,且员工数字段的父节点不是h3标签,必然触发找不到元素的报错。 - 类名定位范围过大:
info__value--2AHH7是页面所有公司关键指标的通用值类名,页面中存在十余个匹配该类名的元素,直接按类名查找返回的是第一个匹配项(通常为总部地址等字段),不是目标员工数。
不要依赖nth-child位置定位元素,页面字段顺序调整就会失效,直接通过标签文本「Employees」定位相邻数值节点,稳定性更高。
批量爬取报错原因
运行批量代码返回的报错信息如下:
Selenium message:unknown error: unexpected command response
(Session info: chrome=103.0.5060.114)
Build info: version: '4.0.0-alpha-2', revision: 'f148142cf8', time: '2019-07-01T21:30:10'
System info: host: 'DESKTOP-VCCIL8P', ip: '192.168.1.249', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_311'
Driver info: driver.version: unknown
触发该报错的核心原因是版本兼容问题:
- 本地Chrome实际版本为
103.0.5060.114,代码中指定的chromedriver版本为103.0.5060.53,小版本不匹配会导致驱动和浏览器通信异常。 - RSelenium默认调用的Selenium 4.0.0-alpha-2是2019年发布的早期测试版本,和新版Chrome、chromedriver的通信协议存在已知兼容bug。
除此之外代码本身存在两个逻辑缺陷:
- 对
numEmp列重复赋值,先设为字符串类型的"NA",又马上覆盖为空数值向量,容易触发类型转换错误。 - 页面导航后没有预留渲染等待时间,直接抓取源码很可能拿到还未加载完成的DOM结构,导致字段提取失败。
修复后可运行代码
library(RSelenium) library(rvest) library(netstat) library(dplyr) # 启动浏览器驱动,chromever版本需和本地Chrome完全一致 rs_driver_object <- rsDriver( browser = 'chrome', chromever = '103.0.5060.114', verbose = FALSE, port = free_port() ) remDr <- rs_driver_object$client # 设置页面加载超时时间为10秒 remDr$setTimeout(type = "page load", milliseconds = 10000) # 初始化数据集 Data <- data.frame( url = c( "https://fortune.com/company/walmart/", "https://fortune.com/company/amazon-com/", "https://fortune.com/company/apple/", "https://fortune.com/company/cvs-health/", "https://fortune.com/company/jpmorgan-chase/", "https://fortune.com/company/verizon/", "https://fortune.com/company/ford-motor/", "https://fortune.com/company/general-motors/", "https://fortune.com/company/anthem/", "https://fortune.com/company/centene/", "https://fortune.com/company/fannie-mae/", "https://fortune.com/company/comcast/", "https://fortune.com/company/chevron/", "https://fortune.com/company/dell-technologies/", "https://fortune.com/company/bank-of-america-corp/", "https://fortune.com/company/target/" ), numEmp = NA_character_, stringsAsFactors = FALSE ) for (i in seq_along(Data$url)) { remDr$navigate(url = Data$url[i]) # 等待3秒让动态内容渲染完成,可根据本地网速调整 Sys.sleep(3) pgSrc <- remDr$getPageSource() pgCnt <- read_html(pgSrc[[1]]) # 通过文本定位员工数字段,不受字段顺序变动影响 emp_val <- pgCnt %>% html_nodes(xpath = "//div[text()='Employees']/following-sibling::div") %>% html_text(trim = TRUE) # 处理空值情况 Data$numEmp[i] <- ifelse(length(emp_val) > 0, emp_val, NA_character_) # 随机等待1-2秒,降低请求频率避免被拦截 Sys.sleep(sample(1:2, 1)) } # 爬取完成后关闭驱动和浏览器,释放端口 remDr$close() rs_driver_object$server$stop() # 输出提取结果 print(Data$numEmp)
内容的提问来源于stack exchange,提问作者Xian Zhao
相关产品推荐
相关产品推荐

