【问题标题】:How to download a webpage and parse in SQL如何下载网页并在 SQL 中解析
【发布时间】:2016-04-10 16:44:01
【问题描述】:

我只是想下载一个网页并将其以可访问的格式存储在 SQL Server 2012 中。我已经求助于使用动态 SQL,但也许有一种更清洁、更简单的方法来做到这一点。我已经能够使用下面的代码成功地将 htm 文件下载到我的本地驱动器,但是我在使用 html 本身时遇到了困难。我正在尝试将网页转换为 XML 并从那里解析,但我认为我没有正确解决 HTML 到 XML 的转换问题。

我收到以下错误,“不允许使用内部子集 DTD 解析 XML。使用带有样式选项 2 的 CONVERT 来启用有限的内部子集 DTD 支持”

DECLARE @URL      NVARCHAR(500);
DECLARE @Ticker   NVARCHAR(10)
DECLARE @DynamicTickerNumber INT
SET @DynamicTickerNumber = 1

CREATE TABLE Parsed_HTML(
[Date] DATETIME
,[Ticker]    VarChar (8)
,[NodeName] VarChar (50)
,[Value]    NVARCHAR (50));

WHILE @DynamicTickerNumber <= 2
BEGIN

SET @Ticker = (SELECT [Ticker] FROM [Unique Tickers Yahoo] WHERE [Unique Tickers Yahoo].[Ticker Number]= @DynamicTickerNumber)

SET @URL ='http://finance.yahoo.com/q/ks?s=' + @Ticker + '+Key+Statistics'

DECLARE @cmd      NVARCHAR(250);
DECLARE @tOutput  TABLE(data NVARCHAR(100));
DECLARE @file     NVARCHAR(MAX);

SET @file='D:\Ressources\Execution Model\Execution Model for SQL\DB Temp\quoteYahooHTML.htm'
SET @cmd ='powershell "(new-object System.Net.WebClient).DownloadFile('''+@URL+''','''+@file+''')"'

EXEC master.dbo.xp_cmdshell @cmd, no_output

CREATE TABLE XmlImportTest
(
xmlFileName VARCHAR(300),
xml_data xml
);

DECLARE @xmlFileName VARCHAR(300)
SELECT  @xmlFileName = 'D:\Ressources\Execution Model\Execution Model for SQL\DB Temp\quoteYahooHTML.htm'


EXEC('
INSERT INTO XmlImportTest(xmlFileName, xml_data)

SELECT ''' + @xmlFileName + ''', xmlData 
FROM
(
SELECT  * 
FROM    OPENROWSET (BULK ''' + @xmlFileName + ''' , SINGLE_BLOB) AS XMLDATA
) AS FileImport (XMLDATA)
')

DECLARE @x XML;
DECLARE @string VARCHAR(MAX);
SET @x = (SELECT xml_data FROM XmlImportTest)
SET @string = CONVERT(VARCHAR(MAX), @x, 1);

INSERT INTO [Parsed_HTML] ([NodeName], [Value])
SELECT [NodeName], [Value] FROM dbo.XMLTable(@string)
--above references XMLTable Parsing function that works consistently

END

不幸的是,这需要在 SQL Server 范围内运行,我的理解是 HTML Agility Pack 不能立即兼容。我还注意到中间表 XMLimportTest 永远不会被填充,因此这可能不是 HTML 格式错误的函数。

【问题讨论】:

  • HTML 并不总是可以转换成 XML。它可能包含诸如未关闭的
    标记或包含无法解析的 的脚本之类的内容。这就是我使用诸如 HTML AgilityPack 之类的抓取库的原因。此外,一些网页有 HTML 语法错误,例如一个未闭合的 div 或 p 标签。
  • 您使用的代码似乎没问题...如果这是您自己用干净的 XHTML 完成的网站,您可以将其转换为 XML 并依赖其有效性。但在任何其他情况下,您都不能。首先尝试将文件导入表中的NVARCHAR(MAX) 类型的列。如果它允许你投射它(试试CONVERT(XML, YourData, 2)),那就开心吧!如果没有,您将不得不解析出您的数据(SUBSTRINGPATINDEXCHARINDEX ...)
  • 谢谢,Shnugo。它允许我进行转换,但转换会引发错误。我认为这是因为 HTML 不干净。请问一下,如果我知道html标记,有没有一种简单的方法可以隔离一小段HTML数据?
  • 请使用编辑选项将示例 HTML 和预期输出添加到您的问题中

标签: sql sql-server xml web-scraping dynamic-sql


【解决方案1】:

简短回答:不要。

SQL 在某些方面非常有用,但对于下载和解析 HTML,这是一个糟糕的选择。在您的示例中,您使用 PowerShell 下载文件,为什么不在 PowerShell 中解析 HTML 呢?然后,您可以将解析后的数据写入 CSV 文件之类的文件中,然后使用 OPENROWSET 将其加载。

另一种选择,仍然不使用 SQL,但在 SQL Server 中使用更多可能是通过SQL CLR 使用 .Net SP。

正如一些 cmets 指出的那样,如果您可以保证 HTML 是格式良好的 XML,那么您可以使用 SQL XML 功能来解析它,但网页很少是格式良好的 XML,因此这是一个冒险的选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-05
    • 2012-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    相关资源
    最近更新 更多