在 R 中使用 phantomJS 抓取具有动态加载内容的页面

2023-12-26

背景我目前正在使用 rvest 从 R 的一些网站上抓取产品信息。这适用于除一个网站之外的所有网站,其中内容似乎是通过 angularJS(?)动态加载的,因此无法迭代加载,例如通过 URL 参数(就像我对其他网站所做的那样)。具体网址如下:

http://www.hornbach.de/shop/Badarmaturen/Waschtischarmaturen/S3584/artikelliste.html http://www.hornbach.de/shop/Badarmaturen/Waschtischarmaturen/S3584/artikelliste.html

请记住,我的计算机没有管理员权限,只能实施不需要或仅一次性授予管理员权限的解决方案

所需输出最后,R 中的表格包含产品信息(例如标签、价格、评级)=> 不过,在这个问题中,我纯粹需要帮助来动态加载和存储网站;我可以自己处理 R 中的后处理。 如果你能把我推向正确的方向,那就太好了;也许下面列出的我的方法之一是正确的,但我似乎无法将这些方法转移到指定的网站。

目前的方法我发现 phantomJS 作为一个无头浏览器,据我所知应该能够处理这个问题。我对 Java 脚本几乎一无所知,并且语法与我更习惯的语言(R、Matlab、SQL)有很大不同(至少对我来说),我真的很难实现其他地方建议的可能适用的方法我的代码。 基于这个例子 https://gist.github.com/flovv/91453712e8a6ba957e63(非常感谢)我设法使用以下代码从显示的第一个页面至少检索信息:

R:

require(rvest)

## change Phantom.js scrape file
url <- 'http://www.hornbach.de/shop/Badarmaturen/Waschtischarmaturen/S3584/artikelliste.html'

lines <- lines <- readLines("scrape_final.js")
lines[1] <- paste0("var url ='", url ,"';")
writeLines(lines, "scrape_final.js")

## Download website
system("phantomjs scrape_final.js")

### use Rvest to scrape the downloaded website.
web <- read_html("1.html")
content <- html_nodes(web, 'div.paging-indicator')# %>% html_attr('href')
content <- html_text(content) %>% as.data.frame()

以及相应的 PhantomJS 脚本:

var url ='http://www.hornbach.de/shop/Badarmaturen/Waschtischarmaturen/S3584/artikelliste.html';
var page = new WebPage() 
var fs = require('fs'); 

page.open(url, function (status) { 
         just_wait(); 
}); 


function just_wait() { 
    setTimeout(function() { 
              fs.write('1.html', page.content, 'w'); 
           phantom.exit(); 
    }, 2500); 
}  

什么不起作用//研究虽然此代码从第一页检索信息,但我确实需要遍历所有 x 个产品页面。我尝试用以下示例扩展上面的代码:

无法在r中使用phantomjs抓取多个页面 https://stackoverflow.com/questions/33146879/scrape-dynamic-loading-

[使用phantomjs抓取动态加载页面][3]

[R中的网页抓取动态加载数据][4]

这些例子让我想到了这个想法

  • 单击“下一页”按钮
  • 或以某种方式注入正确的分页值

    1. 单击“下一页”按钮

这看起来像下面这样

    var url ='http://www.hornbach.de/shop/Badarmaturen/Waschtischarmaturen/S3584/artikelliste.html';
    var page = require('webpage').create(); 
    var fs = require('fs'); 

    page.open(url, function (status) { 
    age.open(url, function() {
      page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() {
        page.evaluate(function() {
          $("paging-btn right").click();
            just_wait(); 
        });
        phantom.exit()
      });

    }); 


    function just_wait() { 
        setTimeout(function() { 
                  fs.write('1.html', page.content, 'w'); 
               phantom.exit(); 
        }, 2500); 
    } 

但由于语法不佳以及其他原因,这对我没有任何帮助。 不幸的是,从 R 调用这个脚本不会产生错误,它只是运行了很长时间,所以我必须退出它(而工作脚本只需要几秒钟)。

我使用 Firefox 中的小工具检查器来检索按钮名称,但这也可能是错误的:

<a class="paging-btn right rel="next" ng-click="goToNextPage()" 
ng-hide="articleData.pageNumber == articleData.pageCount" 
href="javascript:void(0);">right</a> 
  1. 更改加载时的分页参数

我尝试处理这里给出的示例将变量传递到 page.evaluate - PhantomJS https://stackoverflow.com/questions/15356219/passing-variable-into-page-evaluate-phantomjs

但也刚刚得到了一个在 R 中永远不会结束的脚本

补充笔记看起来我只能发布两个链接,所以不幸的是我无法链接我研究和测试过的所有来源。

我很清楚这是一次巨大而混乱的信息,如果您可以帮助我改进/更好地构建我的问题,请告诉我。我会尽力做出回应并为您提供任何您需要的帮助。


我将 PhantomJS 代码分成两部分,以避免出现错误消息。我非常有信心可以先读取并存储网站,然后单击“下一页”按钮并输出新的网址,但不幸的是,这并没有在没有错误消息的情况下成功。

下列R code是最内部的抓取循环(从一个子子类别的页面检索信息,相应地调用/更改 PhantomJS 脚本)。

   for (i3 in 1:num_prod_pages) {

      system('phantomjs readhtml.js') # return html of current page via PhantomJS

      ### Use Rvest to scrape the downloaded website.

      html_filename <- paste0(as.character(i3), '.html') # file generated in PhantomJS readhtml.js
      web <- read_html(html_filnamee)
      content <- html_nodes(web, 'div.article-pricing') # %>% html_attr('href')
      content <- html_text(content) %>% as.data.frame()

      ### generate URL of next page

      url_i3 <- capture.output(system("phantomjs nextpage.js", intern = TRUE)) %>%
         .[length(.)] %>% # last line of output contains 
         str_sub(str_locate(., 'http')[1], -2) # cut '[1] \' at start and ' \" ' at end

      # Adapt PhantomJS scripts to new url

      lines <- readLines("readhtml.js")
      lines[2] <- paste0("var url ='", url_i3 ,"';")
      lines[11] <- paste0("              fs.write('", as.character(i3), ".html', page.content, 'w');")
      writeLines(lines, "readhtml.js")

      lines <- readLines("nextpage.js")
      lines[2] <- paste0("var url ='", url_i3 ,"';")
      writeLines(lines, "nextpage.js")
   } 

下列PhantomJS 代码“readhtml.js”代码在本地存储具有当前 URL 的网站

var webPage = require('webpage');
var url ='http://www.hornbach.de/shop/Badarmaturen/S476/artikelliste.html';
var fs = require('fs'); 
var page = webPage.create();
var system = require('system');

//page.settings.userAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0'
page.settings.userAgent = 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)'

page.open(url, function(status) {
    if (status === 'success') {
        fs.write('1.html', page.content, 'w'); 
        console.log('htmlfile ready');
        phantom.exit(); 
    }
})

下列PhantomJS 代码“nextpage.js”代码点击“下一页”按钮并返回新的 URL

var webPage = require('webpage');
var url ='http://www.hornbach.de/shop/Badarmaturen/S476/artikelliste.html';
var fs = require('fs'); 
var page = webPage.create();
var system = require('system');

page.settings.userAgent = 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0';

page.open(url, function(status) {
    if (status === 'success') {
        page.evaluate(function() {
            document.querySelector('a.right:nth-child(3)').click();
        });
        setTimeout(function() {
            var new_url = page.url;
            console.log('URL: ' + new_url);
            phantom.exit();
    }, 2000);
    };
});

总而言之,不是很优雅,但缺乏其他输入,我关闭了这个输入,因为它工作时没有任何错误消息

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 R 中使用 phantomJS 抓取具有动态加载内容的页面 的相关文章

  • 在多个动态添加的表单上初始化 jQuery validate() 函数

    有人建议最好初始化一个 form validate 在页面加载而不是点击事件上运行 jquery form validate 插件仅允许在输入更改时提交 https stackoverflow com questions 10984196
  • 如何取消 AjaxForm 上的提交

    我正在使用 jQuery 插件 ajax 形式 我尝试实现这样的东西 MyFormID ajaxForm dataType json resetForm true beforeSubmit function validateData ret
  • AngularJS 在指令运行之前通过 AJAX 检索数据

    我正在使用 AngularUIuiMap http angular ui github com directives map实例化谷歌地图的指令 uiMap 指令非常适合处理硬编码数据 mapOptions and myMarkers 但是
  • 搜索多维数组 JavaScript

    我有一个如下所示的数组 selected products 0 r1 7up 61 Albertsons selected products 1 r3 Arrowhead 78 Arrowhead selected products 2 r
  • 在一个项目中使用多个 Javascript 框架?

    在一个项目中使用多个框架是好是坏 还是不好 因为它会变得混乱 一团糟 并且加载时间可能会更长 100 K 真的很重要吗 或者你应该坚持使用一个 通常最好选择一件事并坚持下去 原因有很多 更少的依赖 降低复杂性 更容易维护 更快的加载时间 不
  • jQuery Find() 和 XML 在 IE 中不起作用

    我正在尝试使用 jQuery 来解析内存中的 XML 文档 除了 IE 之外 这在所有东西上都很有效 令人震惊 一些谷歌搜索显示 问题很可能是由于 IE 将我的文档视为 HTML 而不是 XML MIME 类型 有没有办法让我的 jQuer
  • Python Scrapy:allowed_domains从数据库添加新域

    我需要向 allowed domains 添加更多域 因此我没有收到 已过滤的异地请求 我的应用程序获取从数据库获取的网址 因此我无法手动添加它们 我试图覆盖蜘蛛init 像这样 def init self super CrawlSpide
  • ng-model 中的传递函数

    例如 是否可以将函数传递到 ng model 中
  • jquery select 如果 option.value 等于某个值,则标记为选中

    我有一些关于 jquery 选择的问题 就我而言 如果option value等于某物 标记 aselected为了它 在线代码在这里 http jsfiddle net WnEfJ 再次重复代码 它引起了Uncaught TypeErro
  • 使用 JavaScript 在日期中添加小时和分钟

    我正在根据世界各地的时区构建会议日历 我的问题是如何在 JavaScript 中从用户选择的日期中添加或减去时区 例如 在选择表单上 用户将从表单中选择日期 然后我将获取结果并转换为日期 如下所示 var ldSelectDate new
  • jQuery.post 改变 HTML 中的一些特殊字符

    TinyMCE 中的示例数据 和 以上HTML代码 p 10003 and 9786 9999 9986 p 之前 工作正常 在保存的文档中获得相同的字符 function save and submit var tinyGenData t
  • 下划线反跳与参数

    假设我有这个事件处理程序 var mousewheel function e blah 但是 我想消除它 所以我这样做 它按预期工作 var mousewheelDebounced debounce mousewheel 500 docum
  • 当所选选项是下拉列表中已选择的选项时如何接收事件?

    动机 我想动态加载一个select使用来自 AJAX 调用的值 并允许用户select加载后列表中的第一项after它获得焦点 现在 第一项是selected项目 当您单击下拉列表并单击第一项时 什么也没有发生 我无法添加任何无效选择的占位
  • 如何处理并不总是返回承诺的函数?

    处理函数并不总是返回 Promise 的情况的最佳方法是什么 我的实际代码太复杂 无法解释 但问题的本质归结为检查条件 根据它 我要么返回一个局部变量 要么需要发送一个 ajax 请求 像这样的事情 function example val
  • 如何在 AngularJS 中设置和使用 $anchorScroll 的 yOffset 属性

    我用 anchorScroll AngularJS 中的服务 效果很好 但我在顶部有一个固定的导航栏 滚动位置总是 x 像素远 现在在 anchorScroll文档 https docs angularjs org api ng servi
  • VBA / HTML / jQuery 选择自动完成 - 在列表中选择

    我正在尝试使用 Excel 中的 VBA 在网站的列表中选择一个值 这不是一个 正常列表 该网站使用 jQuery 选择自动完成 如下所示 example http davidwalsh name demo jquery chosen ph
  • 检查 touchend 是否在拖动后出现

    我有一些代码可以更改表的类 在手机上 有时表格对于屏幕来说太宽 用户将拖动 滚动来查看内容 但是 当他们触摸并拖动表格时 每次拖动都会触发 touchend 如何测试触摸端是否是触摸拖动的结果 我尝试跟踪dragstart和dragend
  • IE 中的 jQuery .width(val) 错误 - 无效参数

    通过ajax加载内部div book table 后 我想调整正文的宽度以适应更大的内容 var new width parseInt book table css width 407 body width new width 在 FF 和
  • JQuery 验证在 IE8 中不起作用

    我使用 JQuery 验证脚本来验证 HTML 表单 这在 Firefox 中完美运行 但在 IE8 中不起作用 我认为冒号 或分号 有问题 但我无法抓住它 jQuery validator addMethod selectNone fun
  • Jquery - 通过在字符串中构建 id 的 id 获取元素

    我在使用 jquery 元素时遇到问题 我正在 var 中构造名称 例如 var myId myGotId myId attr title changed myId 返回空 我想通过 id 获取我的元素 但动态构建我的 Id 连接字符串 编

随机推荐

  • 如何在 PostgreSQL 中获取数组的最后一个元素?

    The 关于数组的 PostgreSQL 文档 http www postgresql org docs 9 2 static arrays html提供了一个使用示例 1 访问数组的最后一个元素 然而虽然SELECT arr 2 3 产生
  • Notepad++ 查找文件名

    在Notepad 中 我有时需要打开存在于不同文件夹中的文件 这需要时间才能转到文件夹 并通过Light Explorer搜索文件 Notepad 有什么功能或插件可以让我直接打开文件吗 假设 如果我需要打开一个名为 notepad php
  • 检查元素是否包含#shadow-root

    是否可以查看 Shadow DOM 元素是否存在 我不太关心操纵它 甚至不是真正针对它 我理解封装的原因 但我希望能够根据 Shadow DOM 元素是否存在来设置常规 DOM 中其他元素的样式 有点像 if element id shad
  • Win32/MFC 从客户端矩形获取窗口矩形

    我知道有一个函数可以接受客户端矩形 并将其转换为窗口矩形 我只是找不到 记住它 有谁知道它是什么 它会做类似的事情 const CRect client 0 0 200 200 const CRect window ClientRectTo
  • 插件“FEDERATED”已禁用

    我尝试使用 easyPHP 启动 MySQL 响应是日志文件的警报窗口 主要错误是 通过网上研究 我发现解决方案是将联合选项添加到my ini文件 我这样做了 但它仍然不起作用 以下是日志文件的摘录 以了解更多信息 2013 05 03 1
  • 获取点击元素的ID

    div div div div 尝试此方法来获取单击的元素的 ID 并发出警报 我确信这是我所缺少的一些非常基本的东西 有人可以帮忙吗 这实际上非常基本 停止使用内联事件处理程序
  • 每次尝试以特定顺序循环 3 个线程

    我的问题是如何让一个线程运行 然后再运行一次 然后再次运行 然后它会重复本身 我有一个主文件 private static ThreadManager threadManager public static void main String
  • 通用选择不适用于位类型

    基于这个答案 https stackoverflow com a 18469483 1993545 我尝试为我的桌子创建一个选择 ALTER PROCEDURE Einrichtung Select Parameters with defa
  • 如何在 Jetpack Compose 中向图标添加阴影/边框/高度

    我想在 Jetpack compose 中为我的图标添加阴影 以便图像和文本具有 大致 相似的阴影 Text text HAS SHADOW style MaterialTheme typography body2 copy shadow
  • 打印汉字的ESC/POS命令

    打印机型号 爱普生TM T88V ESC POS命令指南 见P 115 http download delfi com SupportDL Epson Manuals TM T88IV Programming 20manual 20APG
  • 是否需要将原始类型键入枚举?

    我正在浏览NSString查看头文件 看看 Apple 如何编写枚举 并发现了这段代码 enum NSStringEncodingConversionAllowLossy 1 NSStringEncodingConversionExtern
  • Google DataFlow/Python:save_main_session 和 __main__ 中的自定义模块导入错误

    有人可以澄清使用时的预期行为吗save main session和导入的自定义模块 main 我的 DataFlow 管道导入 2 个非标准模块 一个通过requirements txt另一个通过setup file 除非我将导入移至使用它
  • 从txt中解析IP地址

    我正在尝试下载一个txt您可以找到的文件here http proxy ip list com download free proxy list txt 下载文件不是问题 testfile urllib URLopener testfile
  • 创建数组的副本并操作原始数组

    首先我要为我糟糕的英语道歉 我会尽力说得清楚 我有一个 3 维数组 只是一个 2 维数组的数组 我的目标是获取其中一个二维数组 并将其逆时针旋转 90 它看起来像这样 1 2 3 4 5 6 7 8 9 我尝试让它像这样 旋转 3 6 9
  • 发生类型错误:超出翻译容量

    当我运行我的示例时 出现以下类型错误 Translation capacity exceeded In this scope universe contains 21 atoms and relations of arity 8 canno
  • 未捕获的 RangeError:超出了最大调用堆栈大小,JavaScript

    我有个问题 open function type Some code document getElementById type addEventListener click l close type false close function
  • 写入开始后无法设置此属性!在 C# WebRequest 对象上

    我想重用 WebRequest 对象 以便保存 cookie 和会话以供以后向服务器请求 下面是我的代码 如果我第二次使用 Post 函数两次 request ContentLength byteArray Length 它会抛出异常 写入
  • 分叉的 IORef 读取器函数似乎会停止主线程

    我正在对并发性和内存可见性进行一些实验 并遇到了这种奇怪的行为 请参阅内联评论 module Main where import Data IORef import Control Concurrent import System CPUT
  • 在 PyQt 中打开第二个窗口

    我正在尝试使用 pyqt 在单击 QMainWindow 上的按钮时显示自定义 QDialog 窗口 我不断收到以下错误 python main py DEBUG Launch edit window Traceback most rece
  • 在 R 中使用 phantomJS 抓取具有动态加载内容的页面

    背景我目前正在使用 rvest 从 R 的一些网站上抓取产品信息 这适用于除一个网站之外的所有网站 其中内容似乎是通过 angularJS 动态加载的 因此无法迭代加载 例如通过 URL 参数 就像我对其他网站所做的那样 具体网址如下 ht