抓取网页数据php(Python中read_html同样提供快捷表格提取需求(图))
优采云 发布时间: 2021-09-10 06:04抓取网页数据php(Python中read_html同样提供快捷表格提取需求(图))
爬取数据时,很大一部分需求是爬取网络上的关系表。
对于表格,R语言和Python都封装了抓取表格的快捷函数。 R语言XML包中的readHTMLTables函数封装了提取HTML嵌入表格的功能,而rvest包的read_table()函数也可以提供快速的表格提取需求。 Python read_html还提供了直接从HTML中提取关系表的功能。
HTML 语法中嵌入的表格有两种,一种是表格,就是通常意义上的表格,另一种是列表,可以理解为列表,但是浏览器渲染出来的网页来自一个角度来看,两者很难区分,因为在效果上几乎没有区别,但是通过开发者工具的后台代码界面,table和list是两个完全不同的HTML元素。
上面提到的函数是针对HTML文档中的不同标签设计的,所以如果你不加区分地使用这些函数来提取表格,对于那些你认为是表格但实际上是列表的人来说很可能是无效的。 .
library("RCurl")
library("XML")
library("magrittr")
library("rvest")
对于 XML 包,有三种提取 HTML 元素的快捷函数。它们用于 HTML 表格元素、列表元素和链接元素。这些快捷功能都是:
readHTMLTable() #获取网页表格
readHTMLList() #获取网页列表
getHTMLlinks() #从HTML网页获取链接
读取HTML表格
readHTMLTable(doc,header=TRUE)
#the HTML document which can be a file name or a URL or an
#already parsed HTMLInternalDocument, or an HTML node of class
#XMLInternalElementNode, or a character vector containing the HTML
#content to parse and process.
此功能支持的 HTML 文档格式非常广泛。 doc 可以是 url 链接、本地 html 文档、已解析的 HTMLInternalDocument 组件或提取的 HTML 节点,甚至可以是收录 HTML 语法元素的字符串向量。
以下是一个案例。也是我自学爬行的时候爬的一个网页。以后可能会有改版。很多朋友爬不出来那些代码,问我这是怎么回事。我已经尝试了以下但我没有工作。我今天借此机会重新整理了一下思路。
大连市2016年空气质量数据可视化~
URL% xml2::url_escape(reserved ="][!$&'()*+,;=:/?@#")
####
关于网址转码,如果你不想使用函数进行编码转换,
可以通过在线转码平台转码后赋值黏贴使用,但是这不是一个好习惯,
在封装程序代码时无法自动化。
#http://tool.oschina.net/encode?type=4
#R语言自带的转码函数URLencode()转码与浏览器转码结果不一致,
所以我找了很多资料,在xml2包里找打了rvest包的url转码函数,
稍微做了修改,现在这个函数你可以放心使用了!(注意里面的保留字)
###
mydata% html_table(header=TRUE) %>% `[[`(1)
#关闭remoteDriver对象
remDr$close()
上面两个是等价的,我们得到了完全一样的表数据,数据预览如下:
DT::datatable(mytable)
readHTMLTable 函数和 rvest 函数中的 html_table 可以读取 HTML 文档中嵌入的表格。它们是非常优秀的高级包解析器,但并不意味着它们无所不能。
毕竟,聪明的女人做饭没有米饭是很难的。首先,我们需要得到米饭来做饭,所以在读取表格时,最好的方式是使用请求库请求(RCurl 或 httr),然后使用 readHTMLTable 请求返回的 HTML 文档。函数或者html_table函数来提取表格,否则会适得其反。在今天的情况下,很明显浏览器渲染后可以看到完整的表格,然后后台抓取就没有内容了,也没有提供API访问,也无法获取。对于完整的 html 文档,您应该考虑任何数据隐藏设置。
可以看到这个技巧。既然浏览器可以解析出来,那我就驱动浏览器去获取解析出来的HTML文档,返回解析出来的HTML文档。接下来的工作就是使用这些高级函数来提取嵌入的表。
那么selenium服务器+plantomjs无头浏览器为我们做了什么?其实只做了一件事——帮助我们做一个真实的浏览器请求,这个请求是由plantomjs无头浏览器完成的,是的,它帮助我们传输渲染的完整HTML文档,这样我们就可以使用readHTMLTable函数或者read_table( )
在 XML 包中,还有另外两个非常有用的高级打包功能:
一个用于获取链接,一个用于获取列表。
读取HTML列表
获取HTML链接
/空气/
我随便找了一个天气网站首页,里面有全国各大城市的空气指数数据。这似乎是一张表,但不一定是真的。我们可以使用现有的表函数来试一试。
url% readHTMLTable(header=TRUE)
mylist < url %>% read_html(encoding ="gbk") %>% html_table(header=TRUE) %>% `[[`(1)
NULL
使用上述代码捕获的内容为空。有两个原因。一是html中的标签根本就不是表格格式,也可能是列表。在另一种情况下,表数据像前面的示例一样隐藏。看源码就知道,这一段其实是存放在list unordered list中的,所以用readtable肯定不行。现在是 readHTMLList 函数大显身手的时候了。
header% readHTMLList() %>% `[[`(4) %>% .[2:length(.)]
mylist % html_nodes(".thead li") %>% html_text() %>% `[[`(4) %>% .[2:length(.)]
mylist % htmlParse() %>% readHTMLList() %>% `[[`(4)
虽然成功获得了结果,但遇到了一个令人作呕的编码问题。我不想与各种编码作斗争。我再次使用了phantomjs无头浏览器。毕竟作为浏览器,它总是可以正确解析和渲染。网页内容,无论 HTML 文档的编码声明多么糟糕!
#cd D:\
#java -jar selenium-server-standalone-3.3.1.jar
#创建一个remoteDriver对象,并打开
library("RSelenium")
remDr % readHTMLList() %>% `[[`(8) %>% .[2:length(.)]
#关闭remoteDriver对象
remDr$close()
这次我终于看到了希望。果然,plantomjs浏览器的渲染效果非同凡响!
使用 str_extract() 函数提取城市 id、城市名称、城市污染物指数和污染状况。
library("stringr")
pattern% do.call(rbind,.) %>% .[,1] %>% str_extract("\\d{1,}"),
City = mylist %>% str_extract_all(pattern) %>% do.call(rbind,.) %>% .[,1] %>% str_extract("[\\u4e00-\\u9fa5]{1,}"),
AQI = mylist %>% str_extract_all(pattern) %>% do.call(rbind,.) %>% .[,2] %>% str_extract("\\d{1,}"),
Quity= mylist %>% str_extract_all(pattern) %>% do.call(rbind,.) %>% .[,2] %>% str_extract("[\\u4e00-\\u9fa5]{1,}")
)
DT::datatable(mylist)
最后一个函数是抓取URL链接的高级封装函数,因为在html中,URL标签一般是比较固定的,重定向的URL链接一般在标签的href属性中,图片链接一般在
在标签下的src属性中,最好定位。
找个知乎摄影贴,高清图多的那种!
url% getHTMLLinks()
[1] "/" "/" "/explore"
[4] "/topic" "/topic/19551388" "/topic/19555444"
[7] "/topic/19559348" "/topic/19569883" "/topic/19626553"
[10] "/people/geng-da-shan-ren" "/people/geng-da-shan-ren" "/question/35017762/answer/240404907"
[13] "/people/he-xiao-pang-zi-30" "/people/he-xiao-pang-zi-30" "/question/35017762/answer/209942092"
getHTMLLinks(doc, externalOnly = TRUE, xpQuery = "//a/@href",baseURL = docName(doc), relative = FALSE)
从getHTMLLinks的源码可以看出,这个函数过滤的链接条件只有标签下href属性中的链接。我们可以通过修改xpQuery中的apath表达式参数来获取图片链接。
mylink % htmlParse() %>% getHTMLLinks(xpQuery = "//img/@data-original")
这样就可以轻松获取知乎摄影贴高清图片的所有原创地址,效率高很多。
蟒蛇:
如果不需要python中的爬虫工具,我目前知道的表提取工具是pandas中的read_html函数,相当于一个I/O函数(与read_csv、read_table等其他函数相同) ,和 read_xlsx)。同样适用于上述R语言中第一种情况的天气数据。直接使用pd.read_html函数无法获取表格数据。原因是一样的。 html文档中有数据隐藏设置。
import pandas as pd
url="https://www.aqistudy.cn/historydata/monthdata.php?city=%E5%8C%97%E4%BA%AC"
dfs = pd.read_html(url)
这里我们也使用Python中的selenium+plantomjs工具来请求网页。获取完整的源文档后,使用pd.read_html函数提取出来。
from selenium import webdriver
driver = webdriver.PhantomJS()
driver.get('https://www.aqistudy.cn/historydata/monthdata.php?city=%E5%8C%97%E4%BA%AC')
dfs = pd.read_html(driver.page_source,header=0)[0]
driver.quit()
好吧,它不可能是完美的。对于网页表格数据,pd.read_html函数是一个非常高效的包,但前提是你要保证这个网页中的数据确实是表格格式,网页什么都不做。隐藏措施。
在线课程请点击文末原文链接:
Hellobi 直播 | 9月12日R语言可视化在业务场景中的应用
过去的案例数据,请移至我的GitHub:
/ljtyduyu/DataWarehouse/tree/master/File