爬网

Nokogiri简介,第1部分

我有一个从事销售工作的朋友,他说他一天中的大部分时间都是从受欢迎的网站复制潜在客户的电话号码,然后将其粘贴到Excel电子表格中。 这不仅浪费了他的时间,而且很平凡。 您能想象每周要花几个小时访问网站,只是要将电话号码复制到电子表格中吗? 当然,必须有更好的方法……

什么是刮ing?

抓取是解析HTML文档并从中收集(或抓取-看看我在这里所做的事情)的行为。 这非常简单:查看文档,识别要获取的信息,然后再获取它。 这篇文章将简要介绍如何使用Nokogiri和Open-URI向网页发出请求并从中抓取信息。

什么是开放URI?

Open-URI是一个Ruby模块,它使应用程序可以发出HTTP请求。 为了使帖子尽可能简洁,我们将仅使用open方法(稍后将返回)。 如果您需要其他信息,请随时在此处引用Open-URI文档。

什么是Nokogiri?

还记得Open-URI如何使我们能够发出HTTP请求吗? Nokogiri从该请求中获取响应,并以嵌套节点集合中的字符串形式返回HTML。 收到此回复后,我们可以使用Nokogiri提取所需的信息。 与使用Open-URI一样,我们将仅关注两种Nokogiri方法来帮助我们完成此任务-.css和.text

测试中

如何通过示例了解我们的响应可能是什么样子? 让我们定义一个可以完成两件事的方法:1)向网页发出HTTP请求,以及2)使用Nokogiri将响应转换为一堆嵌套节点(NodeSet)。 让我们看看拿破仑在维基百科上为我们准备的文章:

拿破仑
 定义样本 
url =“ https://zh.wikipedia.org/wiki/拿破仑”
doc = Nokogiri :: HTML(open(url))
文件
结束

在文件底部打印该方法,然后在终端中运行该文件。 返回值如下所示:

  #<Nokogiri :: HTML :: Document:0x3fd069489508 name =“ document” children = [#,#<Nokogiri :: XML :: Element:0x3fd069481c54 name = “ html”属性= [#,#,#] children = [#,#<Nokogiri :: XML :: Element:0x3fd069028a04 name =“ head” children = [#,#<Nokogiri :: XML :: Element:0x3fd06951d370 name =“ meta”属性= [#]>,#,#<Nokogiri: :XML :: Element:0x3fd0690187bc name =“ title” children = [#]>,#,#<Nokogiri :: XML :: Element:0x3fd069010fbc name =“ script” children = [#]>,#,#<Nokogiri :: XML :: Element:0x3fd069501d8c name =“ script” children = [#]> ,# ... 
  #数百行回应... 

哇 这不仅是一堆信息,而且信息的解析极其困难(至少对于人类而言)。 我们可以使用此信息做很多事情,但是再次,为了保持简洁,我们将专注于使用css.text方法来使人类更易读。

.css方法

我们将使用.css方法来帮助解析该巨型字符串。 css方法将css选择器作为参数,并返回与所选元素有关的所有信息。 关于拿破仑的文章很长,我们不希望马上获得太多的信息。 让我们保持简单,并返回目录中列出的文章中每个小节的名称:

内容

让我们使用DevTools元素选择器来查看要映射内容列表所需的元素:

选择选择器

真好! 看起来可以使用span.toctext选择器来获取内容。 让我们编辑我们的方法以获取信息:

 定义样本 
url =“ https://zh.wikipedia.org/wiki/拿破仑”
doc = Nokogiri :: HTML(open(url))
p doc.css(“ span.toctext”)
结束

在文件末尾调用此方法,然后在终端中运行该文件。 您应该收到如下响应:

  [#<Nokogiri :: XML :: Element:0x3fc0c145fcec name =“ span” properties = [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c18417fc name =“ span” attribute = [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c1447930 name =” span“属性= [# ] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c1431c5c name =“ span” attribute = [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c189021c name =“ span” attribute = [# ] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c1879e54 name =” span“ attribute = [#]子级= [## Nokogiri :: XML :: Text:0x3fc0c1456340“埃及探险”>]>,#<Nokogiri :: XML :: Element:0x3fc0c1869c20 name =“ span”属性= [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c1860648 name =“ span“ attribute = [#] children = [#]>, #<Nokogiri :: XML :: Element:0x3fc0c18515e4 name =“ span”属性= [#] children = [#“>,#<Nokogiri :: XML :: Element:0x3fc0c14baffc name =” span“ attribute = [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c18bda8c name =“ span” attribute = [# ] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c18bc7b8 name =“ span”属性= [#] children = [#]>,#<Nokogiri :: XML ::元素:0x3fc0c14ae824 name =“ span”属性= [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c14a7a60 name =“ span”属性= [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c14d387c name =” span“ attribute = [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c14d2f08 name = “ span”属性= [#]儿童= [#] >,#<Nokogiri :: XML :: Element:0x3fc0c14ca0d8 name =“ span”属性= [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c14c3008 name =“ span” attribute = [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c14c2680 name =“ span” attribute = [#] children = [#]>,#< Nokogiri :: XML :: Element:0x3fc0c14f5ee0 name =“ span”属性= [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c14f538c name =“ span” attribute = [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c14f4478 name =“ span”属性= [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c14ef2c0 name =“ span” attribute = [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c14e3830 name =“ span“ attribute = [#]孩子== ## ] >>,# <Nokogiri :: XML :: Element:0x3fc0c14db824 name =“ span”属性= [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c14da17c name =“ span”属性= [#] children = [#]> ,#<Nokogiri :: XML :: Element:0x3fc0c18c9850 name =“ span” attribute = [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c18c90f8 name =“ span” attribute = [#]儿童= [#]>,#<Nokogiri :: XML :: Element:0x3fc0c18c8860 name =“ span”属性= [#] children = [#]>,#<Nokogiri :: XML :: Element :0x3fc0c18c5f5c name =“ span”属性= [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c18c52f0 name =“ span” attribute = [#] children = [#]>,#< Nokogiri :: XML :: Element:0x3fc0c18c4198 name =“ span”属性= [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c14fd76c name =“ span” attribute = [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c14fc8e4 name =” span“属性= [#]儿童= [#]>,#<Nokogiri :: XML :: Element:0x3fc0c18d5ee8名称=“ span”属性= [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c18d577c name =“ span “属性= [#]儿童= [# ]>,#<Nokogiri :: XML :: Element:0x3fc0c18d4fc0 name =“ span” properties = [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c18d48cc name =“ span” attribute = [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c18d4188 name =“ span”属性= [#] children = [#]> ,#<Nokogiri :: XML :: Element:0x3fc0c150997c name =“ span” a  ttributes = [#] children = [#,#< Nokogiri :: XML :: Element:0x3fc0c1508d74 name =“ span”属性= [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c1508360 name =“ span”属性= [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c1519ac0 name =” span“属性= [#]子== ## Nokogiri :: XML :: Text:0x3fc0c15193cc“ References”>]>,#<Nokogiri :: XML :: Element:0x3fc0c1519200 name = “ span”属性= [#]儿童= [#]> ,#<Nokogiri :: XML :: Element:0x3fc0c1518aa8 name =“ span” attribute = [#] children = [#]>,#<Nokogiri :: XML: :Element:0x3fc0c15183c8 name =“ span” properties = [#] children = [#]>,#<Nokogiri :: XML :: Element:0x3fc0c1511c44 name =” span“ attribute = [#] children = [#]>] 

啊! 对我们来说仍然不容易解析。 幸运的是,还有另一种方法可以用来帮助清理此问题: .text

.text方法

我们的css选择器将返回一个节点数组,其中包含与网站HTML相关的信息。 通过链接.text方法,我们只能从响应中提取文本。 让我们再次编辑代码:

 定义样本 
url =“ https://zh.wikipedia.org/wiki/拿破仑”
doc = Nokogiri :: HTML(open(url))
p doc.css(“ span.toctext”)。text
结束

现在我们的响应看起来像这样:

  “原住民和教育事业早期对土伦的围困13旺季米亚尔第一次意大利战役埃及远征法国统治者法国领事馆欧洲临时和平法国帝国第三联盟的战争中东部联盟第四联盟和蒂尔西特的战争宾夕法尼亚半岛战争和埃尔福特争夺了第五联盟的战争关于圣海伦娜之死死亡原因宗教和解宗教解放人格形象改革拿破仑法典战争公制教育记忆和评估批评批评宣传和记忆在法国以外的长期影响婚姻和儿童的书名,样式,荣誉和武器先祖先贤书记 

哇。 那好多了。 但这仍然有些草率。 如何区分每个span ? 好吧,由于css方法返回一个数组,因此只需在其上进行映射即可。 毕竟,我们仍在使用Ruby:

 定义样本 
url =“ https://zh.wikipedia.org/wiki/拿破仑”
doc = Nokogiri :: HTML(open(url))
p doc.css(“ span.toctext”)。map {| span | span.text}
结束

再次运行文件,这是我们得到的信息:

  [“起源和教育”,“早期职业”,“土伦围困”,“ 13旺代米亚”,“第一次意大利战役”,“埃及探险队”,“法国统治者”,“法国领事馆”,“欧洲临时和平” ”,“法国帝国”,“第三联盟战争”,“中东联盟”,“第四联盟和提尔西特战争”,“半岛战争和爱尔福特”,“第五联盟和玛丽·路易丝战争”, “入侵俄罗斯”,“第六联盟战争”,“流放到厄尔巴岛”,“数百天”,“流放到圣赫勒拿岛”,“死亡”,“死亡原因”,“宗教”,“协和”, “宗教解放”,“人格”,“形象”,“改革”,“拿破仑法”,“战争”,“公制”,“教育”,“记忆与评估”,“批评”,“宣传与记忆” ,“在法国境外的长期影响力”,“婚姻和子女”,“标题,样式,荣誉和武器”,“祖先”,“另请参见”,“注释”,“引文”,“参考”,“传记”研究”,“专业研究”,“史学与记忆学”,“外部链接”] 

好多了!

结论

现在,我们对如何使用Nokogori和Open-URI有了更好的了解,请继续尝试一下。 它需要一些实践,但是您真正需要的只是.css.text方法(以及任何其他Ruby方法)来开始。 尝试创建自己的方法,以查看提到“拿破仑”一词的次数,或存在多少个超链接,或者您认为值得探索的其他任何事物。

一定要在以后的这篇文章的第2部分中进行回顾,在该部分中,我们将使用一些面向对象的编程技术以及我们收集的信息来构建整洁的东西。