【问题标题】:Web Scraping: Issues With Set_values and crawlr网页抓取:Set_values 和爬虫的问题
【发布时间】:2018-06-25 17:47:39
【问题描述】:

我的目标:使用 R,从 homedepot 抓取所有灯泡型号和价格。 我的问题:我找不到所有灯泡页面的 URL。我可以抓取一页,但我需要找到一种获取 URL 的方法,以便将它们全部抓取。

理想情况下,我想要这些页面 https://www.homedepot.com/p/TOGGLED-48-in-T8-16-Watt-Cool-White-Linear-LED-Tube-Light-Bulb-A416-40210/205935901

但即使获得这样的列表页面也可以 https://www.homedepot.com/b/Lighting-Light-Bulbs/N-5yc1vZbmbu

我尝试了爬虫 -> 在 homedepot 上不起作用(可能是因为 https?)我试图获取特定页面 我尝试了 Rvest -> 我尝试使用 html_form 和 set_values 将灯泡放在搜索框中,但表单又回来了

[[1]]
<form> 'headerSearchForm' (GET )
  <input hidden> '': 21
  <input text> '': 
  <button > '<unnamed>

并且 set_value 将不起作用,因为 is '' 所以错误又回来了 错误:尝试使用长度为零的变量名。

我也尝试使用粘贴功能和 lapply

tmp <- lapply(0:696, function(page) {
  url <- paste0("https://www.homedepot.com/b/Lighting-Light-Bulbs/N- 
 5yc1vZbmbu?Nao=", page, "4&Ns=None")
  page <- read_html(url)
  html_table(html_nodes(page, "table"))[[1]]
})

我收到错误:html_table(html_nodes(page,"table"))[[1]] 中的错误:脚本越界。

我真的很茫然,任何建议或提示都会非常棒。

【问题讨论】:

    标签: r url web-scraping rvest


    【解决方案1】:

    您可以通过 rvest 和 tidyverse 做到这一点。

    您可以在此页面中找到所有灯泡的列表,每页 24 个灯泡,共 30 页:

    https://www.homedepot.com/b/Lighting-Light-Bulbs-LED-Bulbs/N-5yc1vZbm79

    看看初始页面底部的分页网格。我在它周围画了一个(丑陋的)黄色椭圆形:

    您可以通过关注/提取该分页网格中的链接来提取到列出 24 个灯泡的每个页面的链接。

    然而,仅通过比较 url,就可以明显看出所有页面都遵循一个模式,以“https://www.homedepot.com/b/Lighting-Light-Bulbs-LED-Bulbs/N-5yc1vZbm79”为根,而尾部 最后一位字符代表显示的第一个灯泡,“?Nao=24

    因此,您可以简单地推断出指向灯泡显示的每个 url 的结构。以下命令在 R 中创建这样一个列表:

    library(rvest)
    library(tidyverse)
    
    index_list <- as.list(seq(0,(24*30), 24)) %>% paste0("https://www.homedepot.com/b/Lighting-Light-Bulbs-LED-Bulbs/N-5yc1vZbm79?Nao=", . )
    

    现在,要提取每个灯泡页面的 url,一个函数和 purrt 的 map 函数的组合会派上用场。

    要从索引页面中提取单个灯泡 url,我们可以这样调用:

    scrap_bulbs <- function(url){
       object <- read_html(as.character(url))
       object <- html_nodes(x = object, xpath = "//a[@data-pod-type='pr']")
       object <- html_attr(x = object, 'href')
       Sys.sleep(10) ## Courtesy pause of 10 seconds, prevents the website from possibly blocking your IP
       paste0('https://www.homedepot.com', object)
    }
    

    现在我们将结果存储在 map() 创建的列表中。

    bulbs_list <- map(.x = index_list, .f =  scrap_bulbs)
    unlist(bulbs_list)
    

    完成!

    【讨论】:

    • 谢谢!!一旦我运行了这个,我得到了一个列表,但它不包含任何 URL,只有 [[1]]-[[31]] 并且他们输入的都是 NULL。有没有办法查看列表?以及在将它们用于节点等的 url 时如何引用它?
    • 你好 MtnBee。请重试编辑后的代码。我在 scrap_bulbs() 函数上犯了一个错误。
    • 很高兴它有帮助!如果它有效,请不要忘记为答案投票:)