R语言基于selenium模拟浏览器抓取ASCO数据-连载NO.03

A:当前获取数据的网站是ASCO,xpath代码是对应网站内的搜索框、搜索按钮、翻页等功能,都经过反复验证,可以正确获取需要的数据

B:当前数据获取没有经过海量数据验证,目前经过实际获取的3个关键词数据量在1w左右,所以如果需要百万级等以上的数据还需要更多的避免抓取异常和抓取性能的优化

C:selenium版本不宜过高,会导致java调用不兼容,无法正常启动java服务或者正常拉起浏览器(大概是这个意思),已经尝试过更高版本的selenium

1、目标网站和内容准备

R 复制代码
#添加需要搜索的内容
search_content <- c("content1","content2","content3")
#需要获取数据的网址
spider_url_base <- "https://meetings.asco.org/abstracts-presentations/search?query=*&q=*&sortBy=Relevancy&pageNumber=1&filters=%7B%22meetingTypeName%22:%5B%7B%22key%22:%22ASCO%20Annual%20Meeting%22%7D%5D,%22meetingYear%22:%5B%7B%22key%22:%222025%22%7D%5D%7D&size=20"

2、隐藏selenium特征(简单设置,表头、IP池策略等等都没有做,用处不大,未经过大量验证)

R 复制代码
# 隐藏Selenium特征的JavaScript代码
hide_automation_script <- "
Object.defineProperty(navigator, 'webdriver', {
  get: () => undefined
});
window.chrome = {
  runtime: {},
  // etc.
};
const originalQuery = window.navigator.permissions.query;
window.navigator.permissions.query = (parameters) => (
  parameters.name === 'notifications' ?
    Promise.resolve({ state: Notification.permission }) :
    originalQuery(parameters)
);
"

3、启动java服务和浏览器

R 复制代码
#每次获取xpath位置后点击、发送内容等操作最好间隔点时间,否则极大可能造成操作无效
#启动selenium服务
system("java -jar \"你的selenium文件路径/selenium-server-standalone-3.141.59.jar \" -port 4445",wait = FALSE,invisible = FALSE)

remdr <- remoteDriver(browserName ="firefox",
                      version='0.36.0',
                      port=4445)
#如果port被占用,cmd中查看端口占用netstat -ano
#打开浏览器
remdr$open()

4、跳转至目标网站并处理网站弹窗

R 复制代码
Sys.sleep(runif(1, 2, 5))#暂停下再导航到对应网页
# 导航到目标网页
#跳转到目标网站,注意网站打开的时间消耗
remdr$navigate(spider_url_base )
#这里是为了确认网站的cookies弹窗
url_cookies_accept <- remdr$findElement("xpath", "//button[@id='onetrust-accept-btn-handler'][text()='Accept All']")
Sys.sleep(runif(1, 2, 5))#暂停下再导航到对应网页
url_cookies_accept$clickElement()

# 在每次请求前执行JavaScript
remdr$executeScript(script = hide_automation_script)

5、数据抓取与保存

R 复制代码
#准备好存储数据的表
asco_data_cancer_all <- data.frame()
asco_data_cancer_each<- data.frame()
asco_data_cancer_pageeach<- data.frame()

#搜索了3个关键词,所以最外层循环是3次
for (i in 1:3) {
  # 定位搜索框并输入内容
  search_box <- remdr$findElement(using = "xpath", value = "//*[@id='smallSearchbar']") # 替换为实际的搜索框XPath
  search_box$sendKeysToElement(list(search_content[i])) # 替换为实际的搜索查询
  Sys.sleep(runif(1, 3, 6))#暂停下再点击
  # 定位搜索按钮并点击
  search_button <- remdr$findElement(using = "xpath", value = "//mat-icon[@class='mat-icon notranslate material-icons mat-icon-no-color ng-star-inserted' and @aria-hidden='true']") # 替换为实际的搜索按钮XPath
  Sys.sleep(runif(1, 5, 10))#暂停下再点击
  search_button$clickElement()


  # 获取完整HTML内容,这里是为了获取页数
  page_html_source <- remdr$getPageSource()[[1]]

  cat(sprintf("Progress: %s",str_c( search_content[i],"的文章信息已开始提取,当前时间:",Sys.time())),sep='\n')

    Sys.sleep(runif(1, 5, 9))
    asco_data_cancer_each <- data.frame()
    loop_times=0#初始循环次数,为了知道数据获取的情况
    repeat{
      # 获取完整HTML内容
      page_html_source <- remdr$getPageSource()[[1]]
      page_html_content <- rvest::read_html(page_html_source)
      #获取文章名称
      article_name=page_html_content %>%
        html_nodes(xpath = "//input[contains(@class,'mat-checkbox-input') and contains(@class,'cdk-visually-hidden')]/@aria-label") %>%
        html_text()
      #获取文章类型
      article_type=page_html_content   %>%
        #这个xpath值定位也可以://div/span[@class="ng-star-inserted" and not(span/@class)]
        html_nodes(xpath = "//div[@class='eyebrow'][text()='Abstracts & Presentations']/following-sibling::div//span") %>% 
        html_text()
      #获取文章链接
      article_link=page_html_content   %>%
        html_nodes(xpath = "//asco-link[@class='pseudo-hover']//a[@href]") %>% 
        html_attr('href')
      #每一页数据合并
asco_data_cancer_pageeach=data.frame(article_name[-1],article_type,article_link,cancer_type=search_content[i])
      #当前关键词所有页数据合并
      asco_data_cancer_each=bind_rows(asco_data_cancer_each,asco_data_cancer_pageeach)
      #数据获取进度
      proc.time() - ptm
      current_page_url=remdr$getCurrentUrl()[[1]]#获取当前页面的网址
      Sys.sleep(runif(1, 10, 15))
      #下一页点击
      nextpage_button <- remdr$findElement(using = "xpath", value = "//mat-icon[contains(., 'arrow_right')]") # 
      
      Sys.sleep(runif(1, 6, 10))
      nextpage_button$clickElement()#如果间隔很短点击可能翻页不能及时生效
      Sys.sleep(runif(1, 1, 3))
      nextpage_button$clickElement()#如果间隔很短点击可能翻页不能及时生效
      Sys.sleep(runif(1, 5, 10))
      next_page_url=remdr$getCurrentUrl()[[1]]#获取下一页面的网址
      loop_times=loop_times+1

      cat("翻页前后2个页面是否相同",current_page_url,"第",loop_times,"个",current_page_url==next_page_url,sep="\n")
      if(current_page_url==next_page_url){
        cat("已到达最后一页,URL未变化",
            "当前页:",current_page_url,"下一页:",next_page_url,sep='\n')
        break
      }
    }
  #所有关键词数据合并
  asco_data_cancer_all=bind_rows(asco_data_cancer_all,asco_data_cancer_each)
  Sys.sleep(runif(1, 5, 10))
  #清空搜索框内容
  search_box <- remdr$findElement(using = "xpath", value = "//*[@id='smallSearchbar']") # 替换为实际的搜索框XPath
  Sys.sleep(runif(1, 3, 6))
  search_box$clearElement()#清除搜索框内容

}
相关推荐
kisshuan123964 小时前
【深度学习】【目标检测】基于Mask R-CNN的鱼类尾巴检测与识别
深度学习·目标检测·r语言
_OP_CHEN5 小时前
【测试理论与实践】(九)Selenium 自动化测试常用函数全攻略:从元素定位到文件上传,覆盖 99% 实战场景
自动化测试·python·测试开发·selenium·测试工具·测试工程师·自动化工具
开开心心就好1 天前
系统管理工具,多功能隐私清理文件粉碎工具
java·网络·windows·r语言·电脑·excel·symfony
徐子童1 天前
网络协议---TCP协议
网络·网络协议·tcp/ip·面试题·1024程序员节
kisshuan123961 天前
【植物图像分析系列】:基于Cascade R-CNN的叶片气孔状态识别与分类任务详解_1
分类·r语言·cnn
智航GIS2 天前
10.4 Selenium:Web 自动化测试框架
前端·python·selenium·测试工具
廖圣平2 天前
从零开始,福袋直播间脚本研究【三】《多进程执行selenium》
python·selenium·测试工具
0思必得02 天前
[Web自动化] Selenium基础介绍
前端·python·selenium·自动化·web自动化
测试19982 天前
Web自动化测试入门
自动化测试·软件测试·python·功能测试·selenium·测试工具·测试用例
0思必得02 天前
[Web自动化] Selenium简单使用
前端·python·selenium·自动化·web自动化