使用 nokogiri 干式搜索网站的每个页面

2024-04-24

我想搜索网站的每个页面。我的想法是找到页面上保留在域内的所有链接,访问它们,然后重复。我也必须采取措施,避免重复努力。

所以开始很容易:

page = 'http://example.com'
nf = Nokogiri::HTML(open(page))

links = nf.xpath '//a' #find all links on current page

main_links = links.map{|l| l['href'] if l['href'] =~ /^\//}.compact.uniq 

“main_links”现在是活动页面中以“/”开头的链接数组(应该仅是当前域上的链接)。

从这里我可以将这些链接提供并读取到上面的类似代码中,但我不知道确保不重复自己的最佳方法。我想我在访问它们时开始收集所有访问过的链接:

main_links.each do |ml| 
visited_links = [] #new array of what is visted
np = Nokogiri::HTML(open(page + ml)) #load the first main_link
visted_links.push(ml) #push the page we're on
np_links = np.xpath('//a').map{|l| l['href'] if l['href'] =~ /^\//}.compact.uniq #grab all links on this page pointing to the current domain
main_links.push(np_links).compact.uniq #remove duplicates after pushing?
end

我仍在研究最后一点......但这看起来是正确的方法吗?

Thanks.


其他人建议您不要编写自己的网络爬虫。我同意这一点if性能和稳健性是您的目标。然而,这可能是一个很好的学习练习。你写了这个:

“[……]但我不知道确保我不会重蹈覆辙的最佳方法”

递归是这里的关键。像下面的代码:

require 'set'
require 'uri'
require 'nokogiri'
require 'open-uri'

def crawl_site( starting_at, &each_page )
  files = %w[png jpeg jpg gif svg txt js css zip gz]
  starting_uri = URI.parse(starting_at)
  seen_pages = Set.new                      # Keep track of what we've seen

  crawl_page = ->(page_uri) do              # A re-usable mini-function
    unless seen_pages.include?(page_uri)
      seen_pages << page_uri                # Record that we've seen this
      begin
        doc = Nokogiri.HTML(open(page_uri)) # Get the page
        each_page.call(doc,page_uri)        # Yield page and URI to the block

        # Find all the links on the page
        hrefs = doc.css('a[href]').map{ |a| a['href'] }

        # Make these URIs, throwing out problem ones like mailto:
        uris = hrefs.map{ |href| URI.join( page_uri, href ) rescue nil }.compact

        # Pare it down to only those pages that are on the same site
        uris.select!{ |uri| uri.host == starting_uri.host }

        # Throw out links to files (this could be more efficient with regex)
        uris.reject!{ |uri| files.any?{ |ext| uri.path.end_with?(".#{ext}") } }

        # Remove #foo fragments so that sub-page links aren't differentiated
        uris.each{ |uri| uri.fragment = nil }

        # Recursively crawl the child URIs
        uris.each{ |uri| crawl_page.call(uri) }

      rescue OpenURI::HTTPError # Guard against 404s
        warn "Skipping invalid link #{page_uri}"
      end
    end
  end

  crawl_page.call( starting_uri )   # Kick it all off!
end

crawl_site('http://phrogz.net/') do |page,uri|
  # page here is a Nokogiri HTML document
  # uri is a URI instance with the address of the page
  puts uri
end

简而言之:

  • 使用以下方式跟踪您浏览过的页面Set。这样做不是通过href值,但由完整的规范 URI 决定。
  • Use URI.join将可能的相对路径转换为相对于当前页面的正确 URI。
  • 使用递归继续抓取每个页面上的每个链接,但如果您已经看过该页面,则退出。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 nokogiri 干式搜索网站的每个页面 的相关文章

  • 在单选按钮选择上提交 Rails 表单

    我有以下 Rails 表单 有效 但我想删除 Submit tag 并在选择单选按钮后立即提交表单 我怎么做 p nbsp nbsp p p p 所以我找到了精确的解决方案 感谢输入人员 它帮助我重新定义了我的谷歌搜索
  • 从循环中删除重复项

    我有以下代码 for i in 0 sold length 1 duplicate sold i print duplicate check duplicates print print sold i lotnumber t print s
  • 用 ruby​​ 解决旅行商问题(50 多个位置)

    我在一家快递公司工作 目前 我们 手动 解决了 50 多个地点的路线 我一直在考虑使用 Google Maps API 来解决这个问题 但我读到有 24 点的限制 目前我们在服务器中使用 Rails 因此我正在考虑使用 ruby 脚本来获取
  • Sinatra 请求对象

    我可能在这里遗漏了一些非常明显的东西 但我似乎无法找到答案 或者自己解决它 在西纳特拉 他们有一个self get方法 捕获块 当调用块时 您可以使用request里面有变量 这怎么可能 Sinatra module Sinatra cla
  • Ruby 枚举器链接

    在这个例子中 1 2 3 each with index map i j i j gt 0 2 6 我的理解是 既然each with index枚举器链接到map map表现得像each with index通过在块内传递索引 并返回一个
  • 如何在 Ruby 中获取网页的 HTML 源代码 [重复]

    这个问题在这里已经有答案了 在 Firefox 或 Safari 等浏览器中 打开网站后 我可以右键单击该页面 然后选择以下内容 查看页面源代码 或 查看源代码 这显示了该页面的 HTML 源代码 在 Ruby 中 是否有一个函数 也许是一
  • R 在 readHTMLTable 调用维基百科时崩溃

    尝试抓取维基百科页面 类似的事情我之前已经做过很多次了 library XML myURL lt http en wikipedia org wiki List of US Open MenUs Singles champions y lt
  • Ruby 安装由于缺少扩展而中止:openssl、readline、zlib 编译错误

    我正在使用 macOS Catalina 我正在尝试通过 rbenv 安装旧版本的 Ruby 1 9 3 2 1 2 但是 在尝试安装旧版本时 我不断收到以下错误 安装 2 4 或更新版本时没问题 我已经尝试过 brew install o
  • 如果公司使用 C++、C# 或 Java 作为应用语言,为什么还要学习 Perl、Python、Ruby? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我想知道为什么 C C Java 开发人员想要学习动态语言 假设公司不会将其主要开发语言从 C C Java 切换到动态语言 那么动态
  • 使用 ruby​​ 获取 URL 的内容长度

    我正在尝试编写一个 ruby 脚本 该脚本使用以下命令获取有关网站上文件的一些详细信息net http 我的代码如下所示 require open uri require net http url URI parse asset res N
  • gem 如何提供 Cucumber 功能和步骤定义?

    我有两个 Rails 项目 A 和 B 其中包含以下宝石 project A gem green theme path gt dev themes green theme gem devel tasks path gt dev themes
  • 在类中调用类方法

    我意识到这可能是一个幼稚的问题 但我仍然无法弄清楚如何在 Ruby 类中从另一个方法调用一个方法 即在 Ruby 中可以执行以下操作 class A def met1 end def met2 met1 call to previously
  • Rails 3 ActiveAdmin。如何为关联记录设置默认排序顺序?

    我有一个发货模型和一个发票模型 发票属于装运 所以我添加了一个默认的发货排序顺序 如下所示 config sort order file number desc 但现在我想为发票添加相同的排序顺序 发货表是具有 file number 列的
  • 使用 Assetic PHP 通过 RVM 安装后 Sass 损坏

    我正在尝试设置 Assetic PHP 资源编译器 并且它可以与 CoffeeScript Stylus 和 Less 一起使用 所有 NPM 包都运行良好 然而 对于 Sass 我遇到了问题 以下是我到目前为止所采取的步骤 我安装了 RV
  • Ruby 元编程,RSpec 的“应该”如何工作?

    我正在阅读 RSpec 并试图弄清楚 RSpec 的 应该 是如何实现的 有人可以帮忙解释一下这个函数的元性质是如何工作的吗 代码位于此处 http github com dchelimsky rspec blob master lib s
  • 在初始化程序中重新加载命名空间常量

    今天遇到一个有趣的情况 我不确定如何解决 给定一个带有初始化器的 Rails 应用程序 file config initializers integrations rb Integrations CONFIGS key gt value f
  • Golang 网络爬虫 NTLM 身份验证

    Golang 网络抓取工具需要从经过 NTLM 验证的网页中提取信息 有了有效的用户名和密码 网络抓取工具如何与服务器进行 NTLM 4 次握手 以获得对后面受保护网页的访问权限 url username password http www
  • ruby中如何获取屏幕分辨率

    如何在ruby脚本中获取屏幕分辨率 高度 宽度 在 Linux 上 x y xrandr scan current d x d flatten 在 Windows 上 使用WIN32OLE等 http www ruby forum com
  • FieldPath 字段名称不能包含“.”当尝试使用 AGGREGATE 时

    我的查询有什么问题吗 db table aggregate match gt expr gt and gt eq gt size gt events 4 events 0 updated gt lt gt 2019 05 05 我越来越 M
  • 如何在启动 Rails 控制台时自动运行代码?

    假设每次 Rails 控制台出现时我都想要一个问候语 Scotts MBP 4 ucode scott rails c Loading development environment Rails 4 2 1 Hello there I m

随机推荐

  • 如何将html页面的动态内容转换为pdf

    在 html 页面中 一些标签是使用 jquery 动态创建的 内容是使用 jquery 和 php 从 msql 数据库加载的 我想将这个动态页面转换为pdf 我尝试过以下代码 但它生成 html 页面静态部分的 pdf html cod
  • 在 C++ 中正确地将 `void*` 转换为整数

    我正在处理一些使用外部库的代码 您可以在其中通过void value 不幸的是 前一个处理此代码的人决定通过将整数转换为 void 指针来将整数传递给这些回调 void val 我现在正在努力清理这个混乱 并且我正在尝试确定将整数转换为整数
  • 估计命令如何查找 R 公式中的变量名称?

    我想使用 R 来估计大量模型nls 函数作用于用户定义的函数 由于许多变量在我的规范中是固定的 我想要一种在我的函数中预先设置它们的方法 但我没有正确理解 R 如何在公式中包含的函数中查找变量 我看过 Hadley Wickham 的高级
  • 我无法获取 servlet 页面中的 POST 值?

    我无法在 servlet 页面中获取 POST 值 我之前的问题与这个问题相关 如何从servlet页面中的ajax请求获取数据 https stackoverflow com questions 6042177 how to get th
  • 如何找到已安装的pandas版本

    我在使用 Pandas 的某些功能时遇到问题 如何查看我的安装版本是什么 Check pandas version In 76 import pandas as pd In 77 pd version Out 77 0 12 0 933 g
  • pytorch 中的 autograd 可以处理同一模块中层的重复使用吗?

    我有一层layer in an nn Module并在一次中使用两次或多次forward步 这个的输出layer稍后输入到相同的layer pytorch可以吗autograd正确计算该层权重的梯度 def forward x x self
  • 在应用程序启动时禁用 Windows 服务

    因为我必须在应用程序启动时关闭 Windows 高级文本服务 有什么特殊的API吗 它适用于具有默认权限的用户吗 该问题的标题是 禁用 Windows 服务 但答案都告诉我们如何停止服务 您在 Google 上会发现的大部分内容是 您可以使
  • 无法在 gae 中运行简单的 helloworld (python 2.7)

    我正在尝试运行官方你好世界 https shadyabhi github com shadyabhi helloworld gitgoogle appengine 1 6 4 中用于 python 2 7 的程序 无法运行一个简单的 hel
  • IOCP AcceptEx 在连接时未创建完成

    我目前正在尝试一些用于套接字编程的新库 IOCP 我偶然发现了AcceptEx http msdn microsoft com en us library windows desktop ms737524 28v vs 85 29 aspx
  • 在 Apps 脚本中对同一工作表使用 Google Sheets API

    通过 SpreadsheetApp 全局 使用绑定到电子表格的 Apps 脚本来影响电子表格非常简单 但是 有一些功能 例如在工作表上获取 设置过滤器 只能通过 Google Sheets REST API 访问 我见过一个在 Apps 脚
  • 如何将 Red5 与 Asp.net 结合使用

    我想在线录制语音 我想我需要使用FMS或Red5 但我不知道如何将Red5与Asp net一起使用 实际上这是我第一次尝试处理这样的事情 目前我是一名 net开发人员 所以请有人告诉我一种处理它的方法 并告诉我如何将 Red5 与 Asp
  • 正则表达式:如何匹配包含重复模式的字符串?

    是否有一个正则表达式模式可以匹配包含重复模式的字符串 例如 a b c d y z 你有什么主意吗 也许您正在寻找这样的东西 这将匹配以逗号分隔的表单序列列表 where and 可以是任何字符
  • 使自定义 monad 转换器成为 MonadError 的实例

    我想让我的 monad 转换器成为一个实例MonadError如果转换后的单子是一个实例 基本上我希望我的变压器的行为与内置变压器一样 例如有一个MonadError实例为StateT MonadError e m gt MonadErro
  • 如何从另一个 sbt 项目引用外部 sbt 项目?

    我对 Scala 应用程序和通用核心库进行了以下设置 根 gt ApplicationA gt project gt build sbt gt CoreLibrary gt project gt build sbt 我想将 Applicat
  • 将 Yup 验证错误转换为可用对象

    Problem 我有一个 formik 表单 需要有 2 个不同的验证模式 具体取决于用户使用哪个按钮提交 我看到有些人说使用状态来决定哪个 但我想避免使用状态 因为在这种情况下感觉不对 我看过是的文档 https www npmjs co
  • 格式化整数时 printf 中的精度字段

    当我执行这两行时 printf 5d n 3 use of precision filed printf 05d n 3 use of 0 flag to prepend with 0 我得到以下输出 00003 00003 结果相同 所以
  • Google 字体无法在移动设备中加载

    我读过类似的帖子 但这个问题有点不同 我有 rest of the code 在 css 样式文件中我有 body font family Source Sans Pro sans serif rest of the code 它在浏览器中
  • 将新对象附加到 JSON 文件中的数组

    如何将附加对象添加到现有 JSON 文件 即对象数组 中 这是我的 JS 代码 const fs require fs let Human Name John age 20 Human JSON stringify Human null 2
  • 自动完成搜索字符串的多个部分,然后返回最可能的部分

    有点像这个问题 https stackoverflow com questions 824144 how do i use jquery autocomplete for multiple words 我有很多文本片段 每天都会使用很多很多
  • 使用 nokogiri 干式搜索网站的每个页面

    我想搜索网站的每个页面 我的想法是找到页面上保留在域内的所有链接 访问它们 然后重复 我也必须采取措施 避免重复努力 所以开始很容易 page http example com nf Nokogiri HTML open page link