6

我正在尝试在此链接http://www.rchsd.org/doctors/index.htm?strt=0&ln=&fn=&sp=&grp=&loc=&lng=&gen=中提取数据,R但这相当困难.

我注意到每当我单击页码时,url 链接都不会改变。这个表是用 JavaScript 创建的吗?该表是由某些外部源创建的,我如何访问它?另外,这种类型的表有技术名称吗?

另外,对于任何知道网络抓取或任何其他程序的人R,您将如何从该表中提取所有数据?我尝试使用以下代码R提取数据,但我得到NULL. 你会如何解决这个问题?

mps <- paste("http://www.va.gov/providerinfo/SANDIEGO/index.asp?servicesearch=&specialtysearch=&gendersearch=&sort=&currentPage=1") 
mps.doc <- htmlParse(mps)
mps.tabs <- readHTMLTable(mps.doc)

另外,如果你不能回答我问题的后半部分,那也没关系。我主要想知道我问题前半部分的答案。

4

2 回答 2

5

答案使用 3 种不同的技术进行了修订,全部基于 .ajax() 和 YQL。

技术1

参考 HTML: http ://doctors.ucsd.edu/?index=1

对于您问题的第一部分,您提供的 URL 中的表格类型是标准的HTML 表格模型种类。在创建它table时,该网站使用一个XML 文件来填充它rowscolumns数据,包括医生的照片。

为了让服务器满意,并非XML 文件中的所有数据都加载到浏览器中,仅显示有限的结果,并带有进入下一页的选项。

您写的评论部分中的 URL 链接也是如此(即http://doctors.ucsd.edu/?index=1 ),访问者可以从网页结果每页下拉列表中选择 10、25 或 50 个结果菜单。例如,网络的地址栏将显示请求的号码&setsize=25

尽管您可能希望对引用 URL 进行数据抓取,但最好不要这样做,因为您已经拥有包含所有所需数据的XML 文件。直接访问它的工作量更少!

参考 XML: http ://www.rchsd.org/api/physdir/

您的问题的第二部分很容易,因为XML 文件很容易获得。这一次,当您抓取引用 XML File 的数据时,它会快速显示您正在寻找的信息,并且具有很高的可读性。

在上述两个数据抓取查询中,出于测试目的,我已将请求限制为 5 个结果,但您可以将其增加到更大的采样值。第一个示例中的额外网页数据量需要使用XPATH来映射节点并需要额外处理才能使用该数据。

我准备了一个详细的 jsFiddle,它应该可以解释你关于这个过程的很多问题。在其中,我解释了如何使用 YQL、.ajax()XML 文件的链接。


参考示例:

$.ajax({
    type: 'GET',
    url: 'http://query.yahooapis.com/v1/public/yql?q=SELECT%20phys%20FROM%20xml%20WHERE%20url%3D%22http%3A%2F%2Fwww.rchsd.org%2Fapi%2Fphysdir%2F%22%20LIMIT%205',
    dataType: 'xml',
    success: function(data) {
        var dataResults = $(data).find('results');
        console.log(dataResults);
    }
});

参考教程:
jsFiddle Data Scraping XML DemojsFiddle HTML Demo见下文


技巧2

编辑:返回原始参考 HTML:http ://doctors.ucsd.edu/?index=1

我在第一部分写的最后一件事实际上是不正确的,因为您不一定拥有所需的所有数据。虽然您可以从XML 文件中的物理医生地址创建自己的Google 地图位置数据,但该信息已经可供使用。

然后还发现此 URL 还包含一个独特的格式化缩略图图像,并在可用时包括医生信息部分。

那么,接下来是一个重新编写的 jsFiddle,它展示了如何抓取该 HTML 网页的数据。您将在这个新的 jsFiddle 中注意到YQL 语句不再存在ACCESS phys FROM xml,因为我们现在正在处理 HTML 文档。此外,我们将在该YQL 语句中使用通配符*而不是标记名。届时将physACCESS * FROM html

正如您从上面的数据抓取第一种方法中记得的那样,该请求返回了太多数据。我将解释如何XPATH向该YQL 语句添加一个,以便您只获取所需的数据。

你问从哪里开始?在浏览器中的那个网站上!我将使用 Firefox 继续。

首先,让我们在测试中强制返回 5 个结果。为此,请将Results Per Page更改为 25,然后在浏览器栏中将 25 更改为 5 以进行&setsize=查询。在键盘上按 Enter 以应用更改。

使用网页Additional Search CriteriaShow More SpecialtiesLocationSort results by:也会修改浏览器栏并进一步创建自定义 URL 以供使用。

对于我们的演示,我们只需要对排序结果的 1 个额外自定义:姓氏 AZ。如果需要,请重新加载网页,并确保...我们的自定义 URL 应如下所示:

http://doctors.ucsd.edu/?sortby=familyName&sortDirection=asc&setsize=5

现在网页已经填充了我们请求的 5 个结果,我们需要查看布局如何支持这些项目。

通过右键单击鼠标使用 Firefox Inspect Element工具来查看和学习表格布局结构。很快,您将看到所有返回的结果都包含在一个唯一的类名中。

下面是使用 Firefox 的截图来说明:

在此处输入图像描述

当通过Inspect Element工具底部的图标(在 Inspect Element Icon 的右侧)弹出HTML 面板时,您可以看到单个 Doctors 框的情况:layout

在此处输入图像描述

在上面的照片中,您可以直观地 向上遍历 DOM,看到主类名 resultsListdiv持有请求的 5 个结果。可以使用实际的类名,但要使用的更精致的类名resultsListProvider每个返回的项目所携带的。

您现在拥有构建要使用的 YQL 语句所需的信息。首先,这是我们开始使用的最低要求:

ACCESS * FROM html WHERE url="http://doctors.ucsd.edu/?sortby=familyName&sortDirection=asc&setsize=5"

上面真的不行,因为它返回了太多非必要的网页数据,这就是为什么我们使用Inspect Element来发现什么是真正重要的。话虽如此,我们将使用XPATH通过classname resultsListProvider访问我们需要的网页部分。

xpath="//div[@class='resultsListProvider']"

现在我们可以结合使用这两个部分AND创建我们可以数据抓取的最终 YQL 语句

SELECT * FROM html WHERE url="http://doctors.ucsd.edu/?sortby=familyName&sortDirection=asc&setsize=5" AND xpath="//div[@class='resultsListProvider']"

上面的最终 YQL 语句现在将提供可用的结果,以便在我创建的新 jsFiddle 中使用,它更新了注释以反映这些更改。如果需要,您可以结合XML 文件HTML URL方法来满足您的数据抓取要求,因为每种方法都提供其他方法可能缺少的内容。

提醒:网页加载时或使用YQL Rest State查询时,可能会直接渲染部分数据。这意味着您的动态数据可能基于它们的动态数据天啊!

参考教程:

jsFiddle 数据抓取 HTML 演示请参阅上面的 jsFiddle XML 演示


技巧3

编辑 2:直接使用 HTML

jsFiddle 数据抓取 HTML 演示:克隆该网页

最新的编辑展示了如何使用原始网页的样式表(这是可选的,您可以创建自己的dataType),但使用属性以不同的方式请求 Ajax 数据。使用这种方法将准确的标记放置在本地网页上,包括任何classnamesid's与它一起。

jsFiddle 截图: 在此处输入图像描述

于 2012-12-26T15:54:37.960 回答
2

该表是使用此XML形成的

于 2012-12-25T00:01:28.443 回答