楼主: derekzzy
1235 10

[问答] 想请教一个R爬取动态网页的弹窗内信息的问题 [推广有奖]

  • 0关注
  • 0粉丝

大专生

5%

还不是VIP/贵宾

-

威望
0
论坛币
20 个
通用积分
0.0319
学术水平
0 点
热心指数
0 点
信用等级
0 点
经验
134 点
帖子
13
精华
0
在线时间
60 小时
注册时间
2020-6-24
最后登录
2022-1-13

相似文件 换一批

+2 论坛币
k人 参与回答

经管之家送您一份

应届毕业生专属福利!

求职就业群
赵安豆老师微信:zhaoandou666

经管之家联合CDA

送您一个全额奖学金名额~ !

感谢您参与论坛问题回答

经管之家送您两个论坛币!

+2 论坛币
我需要爬取砂土车这个网页上那些车的信息。网页初始状态下时有很多小黄车车,鼠标点击某一个车时就会出现一个小弹窗,里面有这个车的一些信息(Vehicle、Age Range、source date等等)。请问怎样才能爬取所有小黄车的信息呢?

我最开始的思路是用rseleniumrvest包,然后:
1. remDr$findelement()定位到单个小黄车的图片上面
2. 然后clickelement()模拟左键点击
3. 利用小车的xpathhtml_nodes()html_text()函数来实现爬取并获得该车信息
4. 再用findelement和clickelement模拟点击关闭弹窗的按钮
5. 循环以上操作直到所有车都被爬到


这是我写的部分代码:
#打开网页
remDr = remoteDriver(remoteServerAddr="localhost",port=4444L,browserName="chrome")
remDr$open(silent = T)
url = "https://www.arcgis.com/apps/webappviewer/index.html?id=2de764a9303848ffb9a4cac0bd0b1aab"
remDr$navigate(url)

#模拟鼠标点击小车,打开弹窗信息栏
image_button = remDr$findElement('xpath', value = "//*[@id='TSWT_VehiclesAndTrail_2020_1393_layer']/*[name()='image']")
image_button$clickElement()

#爬取信息栏信息
webpage <- read_html(remDr$getPageSource()[[1]])
data <- webpage %>% html_nodes(".attrValue") %>% html_text()
data



这是我的
但是实际操作起来发现有一些问题。首先没有点弹窗的初始状态下,每个小车的image的结构如下所示:
<svg>
    <g id = xxx>
        <image></image>
        <image></image>
        <image></image>
                     .
                     .
    </g>
</svg>


虽然每个小车的image有各自独有的xPath,但是由于某些原因,可能是因为处在一个多层结构里,直接在findElement()放image的xPath会报错,查询了一些资料后发现可以改变xpath写法,先定位到<g>,再在后面加/*[name()='image']来实现。但是这种方法只能适用于缩放到屏幕上只有一个车,如果有多个车,就定位不了。我试过
remDr$findElement('xpath', value = "//*[@id='TSWT_VehiclesAndTrail_2020_1393_layer']/*[name()='image']")[[1]]

但这样写,会报错,说明在最后加[[1]]这种做法并不能实现从多个小车image中定位到某特定小车image的效果。




所以我想请教一下如何我这种方法是否可行?或者说有没有其他比较简单的做法可以直接获得所有小车弹窗内的内容,而不用不停地模拟点击打开,爬信息,模拟点击关闭这种比较麻烦的触发弹窗?
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

关键词:localhost Vehicles navigate Element Vehicle rvest 爬虫

4d3e3fea313735fda048db84a53a125.png (717.42 KB)

4d3e3fea313735fda048db84a53a125.png

71ba6fc63b9e43df8112422f40c2bdd.png (680.14 KB)

71ba6fc63b9e43df8112422f40c2bdd.png

回帖推荐

szxship 发表于9楼  查看完整内容

下面是我采集第二个表的方法,你可以参考一下 library(RSelenium) library(rvest) library(stringr) library(data.table) remDr <- remoteDriver( browserName = "chrome", remoteServerAddr = "localhost", port = 4444L ) remDr$open() url<-'https://www.arcgis.com/apps/webappviewer/index.html?id=2de764a9303848ffb9a4cac0bd0b1aab' remDr$navigate(url) btn = remDr$findElement("xpath", ...
已有 1 人评分论坛币 收起 理由
cheetahfly + 20 鼓励积极发帖讨论

总评分: 论坛币 + 20   查看全部评分

沙发
derekzzy 发表于 2021-1-29 12:34:41 |只看作者 |坛友微信交流群
https://www.arcgis.com/apps/webappviewer/index.html?id=2de764a9303848ffb9a4cac0bd0b1aab
忘记放网站网址了

使用道具

藤椅
szxship 发表于 2021-1-31 18:38:35 |只看作者 |坛友微信交流群
你在console输入
document.querySelector("#TSWT_VehiclesAndTrail_2020_1393_layer > image:nth-child(02)").e_graphic
看看出来的是不是你要的信息,如果是的话,你只要改nth-child(02)这里02这个数字,遍历数字,就可以得到你要的信息(你可以用Rselenium来运行js,rvest里好像也行,你试一下)

使用道具

板凳
derekzzy 发表于 2021-2-1 15:29:59 |只看作者 |坛友微信交流群
szxship 发表于 2021-1-31 18:38
你在console输入
document.querySelector("#TSWT_VehiclesAndTrail_2020_1393_layer > image:nth-child(02 ...
非常感谢您!现在又有个问题,就是这个网页上最下面有一个按钮,点击后会出现一个包含各种属性信息的弹窗。由于信息很多,这个弹窗是做成自上而下可滚动的滚动栏形式,现在我要爬取滚动栏里所有的信息,但我发现如果在html_nodes ()函数里直接用整个滚动栏的xpath进行搜索,最后反馈的结果只有滚动栏最上面的一小部分,下面大部分的都无法被搜索到。我查了下说的是动态网页滚动栏存在懒显示问题,会导致爬取滚动栏的信息不全,请问您知道有没有什么好的解决方法呢?

使用道具

报纸
szxship 发表于 2021-2-1 21:18:04 |只看作者 |坛友微信交流群
derekzzy 发表于 2021-2-1 15:29
非常感谢您!现在又有个问题,就是这个网页上最下面有一个按钮,点击后会出现一个包含各种属性信息的弹窗 ...
你要的元素是在我截图标示的网址里,你双击打开就可以看到,这些网址是你点击激活后才出现 scrap.png

使用道具

地板
derekzzy 发表于 2021-2-2 11:00:52 |只看作者 |坛友微信交流群
szxship 发表于 2021-2-1 21:18
你要的元素是在我截图标示的网址里,你双击打开就可以看到,这些网址是你点击激活后才出现
感谢!请问有什么函数可以获得GET请求的返回值吗?是用remDr$queryRD 吗?

使用道具

7
szxship 发表于 2021-2-2 21:46:14 |只看作者 |坛友微信交流群
derekzzy 发表于 2021-2-2 11:00
感谢!请问有什么函数可以获得GET请求的返回值吗?是用remDr$queryRD 吗?
这个似乎不行,你把get里得到的网址的最后一个数改得足够大,再用rvest::read_html一次就可以读完,如果你不用这种方法,另一种我能想到的就是利用RSelenium不断的滚动下拉,且每下拉一点就写出一部分数据,我试了一下,这种是可以的,就是有点慢,不像第一种方法,一次读完
已有 1 人评分学术水平 热心指数 信用等级 收起 理由
derekzzy + 1 + 1 + 1 热心帮助其他会员

总评分: 学术水平 + 1  热心指数 + 1  信用等级 + 1   查看全部评分

使用道具

8
derekzzy 发表于 2021-2-3 11:13:57 |只看作者 |坛友微信交流群
szxship 发表于 2021-2-2 21:46
这个似乎不行,你把get里得到的网址的最后一个数改得足够大,再用rvest::read_html一次就可以读完,如果你 ...
谢谢!我昨天试了下不用rvest和rselenium,而是直接把那一整坨url用fromJson() 函数导入,再用r处理json文件的一些方法整理一下,就可以得到整个Vehicle location (current) 表格的一百多条数据,数据量也是对的。但是我尝试用这种方法来处理右边的第二栏Vehicle Trial(0-2hrs)表格的数据时,就出现了问题,由于这一栏数据有一千八百多条,随着滚轮向下滚动,很多xhr产生了,每一个只包含一小部分大概二十多条数据。我尝试用您说的把GET得到的url的最后一个数字改的足够大之后,确实有所改善,但一共一千八百多条数据,无论我把最后的数字改成2000还是改成10000,只能提取其中1000条数据,而不是1817条数据,请问您知道这种情况怎么办吗?或者能展开讲解Rselenium滚动下拉慢慢获取数据是怎么实现的吗?

使用道具

9
szxship 发表于 2021-2-3 21:32:15 |只看作者 |坛友微信交流群

下面是我采集第二个表的方法,你可以参考一下

library(RSelenium)
library(rvest)
library(stringr)
library(data.table)

remDr <- remoteDriver(
  browserName = "chrome",
  remoteServerAddr = "localhost",
  port = 4444L
)

remDr$open()


url<-'https://www.arcgis.com/apps/webappviewer/index.html?id=2de764a9303848ffb9a4cac0bd0b1aab'  
remDr$navigate(url)


btn = remDr$findElement("xpath","//*[@id='widgets_AttributeTable_Widget_30']/div[1]")
btn$clickElement()

Sys.sleep(3)

vtn = remDr$findElement("xpath","//*[@id='dijit_layout_TabContainer_0_tablist_dijit_layout_ContentPane_1']")
vtn$clickElement()

###############################################################################################


n1 = remDr$executesc ript("return document.querySelector('#widgets_AttributeTable_Widget_30_uniqName_0_1_footer > div:nth-child(1)').innerText")[[1]]
n1 = str_extract(n1,"\\d+") %>% as.numeric()
n1

#################################################################################################
h1 = remDr$executesc ript("return document.querySelector('#dgrid_1 > div.dgrid-scroller').scrollHeight;")[[1]]
pu = round(25*h1/n1)#因为一般每次加载25个数,这里设为25,下面的循环同理,如果采集不完整变小此数

datlist = list()
j = 1
remDr$setTimeout(type = "implicit", milliseconds = 15000)#15000加载数据时间,如果采集不完整变大此数
for(i in 0:(round(n1/25))){
	
	txt = remDr$executesc ript("return document.querySelector('#dgrid_1 > div.dgrid-scroller').outerHTML")[[1]]
	wb <- read_html(txt) %>% html_table() %>%  rbindlist()
	datlist[[j]] = wb
	j = j + 1
	remDr$executesc ript(paste0("document.querySelector('#dgrid_1 > div.dgrid-scroller').scrollTo(",i*pu,',',(i+1)*pu,')'))
	Sys.sleep(2)
}

dtable = rbindlist(datlist)
unique(dtable)
dtable

已有 1 人评分学术水平 热心指数 信用等级 收起 理由
derekzzy + 1 + 1 + 1 精彩帖子

总评分: 学术水平 + 1  热心指数 + 1  信用等级 + 1   查看全部评分

使用道具

10
szxship 发表于 2021-2-3 21:36:57 |只看作者 |坛友微信交流群
derekzzy 发表于 2021-2-3 11:13
谢谢!我昨天试了下不用rvest和rselenium,而是直接把那一整坨url用fromJson() 函数导入,再用r处理json文 ...
你改大数字都不行,可能是js函数里有设置,那你可以打开往下后几个json文件里的一个,再去改期中一个,它就会从新的地言开始获取,这些文件的地址看起来复杂,其实有些数是随机生成的,你乱改也是可以打开的,只有几个关键参数没有改错就行

使用道具

您需要登录后才可以回帖 登录 | 我要注册

本版微信群
加好友,备注cda
拉您进交流群

京ICP备16021002-2号 京B2-20170662号 京公网安备 11010802022788号 论坛法律顾问:王进律师 知识产权保护声明   免责及隐私声明

GMT+8, 2024-5-18 17:08