【问题标题】:matching common strings between two data sets匹配两个数据集之间的公共字符串
【发布时间】:2011-10-30 21:18:12
【问题描述】:

我正在处理网站转换。我将数据库后端转储为 sql 文件。我还从 wget 抓取了网站。

我想要做的是将数据库表和列映射到抓取中的目录、页面和页面部分。我想自动化这个。

是否有一些工具或脚本可以从一个源中提取字符串并在另一个源中查找它们?理想情况下,它会返回一组结果,类似于

string "piece of website content here" on line 453 in table.sql matches string in website.com/subdirectory/certain_page.asp on line 56.

我不想进行行比较,因为来自数据库转储 (INSERT INTO table VALUES (...)) 的行不会匹配它实际填充的页面中的行 (<div id='left_column'><div id='left_content'>...</div></div>)。

我意识到这是一项计算密集型任务,但即使让它在周末运行也可以。

我发现了类似的问题,但我没有足够的 CS 背景知识来知道它们是否与我的问题相同。所以好心地建议this question,但它似乎正在处理一组已知的针来匹配大海捞针。就我而言,我需要将 haystack 与 haystack 进行比较,并查看匹配的干草吸管。

是否有命令行脚本或命令,或者这是我需要构建的东西?如果我构建它,我应该按照另一个问题中的建议使用 Aho–Corasick 算法吗?

【问题讨论】:

  • 你能详细说明一下这个问题吗?您是否允许预处理这两个转储文件以消除不必要的格式?您是在寻找完整的数据库行匹配,还是只是在一个出现在另一个中的字符串?
  • 我可以稍微处理一下文件。这对于数据库转储来说很容易,但对于网站文件来说即使不是不可能也更难,因为我不能假设它们结构良好。但是,如果我的程序可以进行字符串匹配,为什么还要费心清理文件呢?我只想要映射。
  • 我只是在寻找字符串匹配。 Line 12 of file A has string "piece of content" that matches line 45 of file B
  • 清理文件可能会很好,因为这样您就不会在包含格式和实际文本混合的垃圾字符串之间找到虚假匹配。但是,如果这不是问题,那么您是绝对正确的,您不需要执行此步骤。
  • 我看不出任何虚假匹配的可能性。 sqldump 不会将 HTML 作为元数据。但是,如果它确实将其作为字段数据——这意味着页面内容被存储在数据库中——我会想知道它是否匹配!并且网页文件不会以 DDL 或 DCL 作为内容。

标签: string algorithm search dictionary


【解决方案1】:

这行不通,至少不可靠。最佳情况:您可以将每条数据与其对应的 HTML 文件相匹配,但您会遇到很多误报。例如用户名是实际的单词等。

此外,文本通常会在显示之前进行处理。网站通常将标题大写或截断文本以进行预览等。

AFAIK 没有这样的工具,在我看来,也不存在可以充分解决您的问题的工具。

您最好的选择是获取网站使用/使用的源代码并对其进行分析。如果失败/不可能,您必须手动分析数据库。从 URL 中获取尽可能多的内容并尝试解决难题。

【讨论】:

  • 我不在乎用户名是不是真实的单词;我只关心它们是否出现在网站和数据库转储中。
  • 我的意思是:“Hello to my super Hello World programm...”将与可能的用户名“hello”匹配 2 次,在语义上这是错误的。抱歉让朋友失望了。我只是想节省你寻找圣杯的时间,但无论如何。
  • 那是一场我想知道的比赛。如果数据库中出现了不是 DDL、DCL 或 SQL 关键字的字符串“Hello”,我想在网站上查看它匹配的内容。我可以更快地浏览错误匹配列表,而不是将 sqldump 与站点抓取进行比较,而这正是您建议做的。
【解决方案2】:

所以您的两个问题是 1) 是否已经有解决方案可以满足您的需求,以及 2) 您是否应该使用 Aho-Corasick 算法。

第一个答案是,我怀疑您会找到满足您需求的现成工具。 第二个答案是,由于您不关心性能并且具有有限的 CS 背景,您应该使用您认为最容易实现的任何算法。

我会更进一步,提出一个架构。

首先,您需要能够将 .sql 文件解析为一种有意义的方式,即逐行返回 tablename、column_name 和 value。 StreamReader 可能最适合这个。

其次,您的网页需要一个解析器,它将逐个元素地返回每个文本节点和每个父元素的名称,一直到 html 元素及其父文件名。 XmlTextReader 或类似的流式 XML 解析器(例如 SAXON)可能是最好的,只要它能够在无效的 XML 上运行。

您需要将这两个解析器与某种相互搜索算法联系在一起。您必须对其进行自定义以满足您的需求。如果你能做到的话,Aho-Corasick 显然会给你带来最好的表现。不过,简单的算法很容易实现,方法如下:

假设您有两个解析器循环遍历每个字段(一方面)和每个文本节点(另一方面),请选择两个解析器中的一个并让它遍历其数据源中的每个字符串,调用另一个解析器来搜索其他数据源以查找所有可能的匹配项,并记录它找到的匹配项。

【讨论】:

  • 我认为最好从 sqldump 中解析一个字典,因为我假设它的至少某些部分正在填充网站,然后将该字典与网站抓取进行匹配。
  • 我正在考虑使用漂亮的汤来解析 html -- 你对撒克逊人有什么想法吗?
  • Beautiful Soup 应该比 lxml 慢得多,因为它使用正则表达式来挖掘元素汤。如果您是正则表达式专家,那就去吧,尽管我认为您将需要一种更加面向 XPath 的方法才能最终到达您想要去的地方。
  • @user151841 - 你应该发布你的答案并接受它。字典方法要好得多。浏览你的 SQL 并为你找到的每个单词制作一个字典。关键是你找到的词。该值是一个元组列表(databaseName、tableName、fieldName、primaryKeyOrRowIndex)。每次您在该键上获得新的命中时,将一个新元组添加到其列表中。然后,您可以搜索 html 文件中的每个文本节点并扫描它们以查找字典中的匹配项,当您找到一个时,记录您删除的所有数据库元组以及匹配节点的文件名和 xpath。不错!
  • 或者使用双字典的方法——除了索引SQL之外,通过遍历每个文件并记录每个文本节点中的每个单词作为字典的键来索引HTML,并且值将成为 html 文件中每个单词的 tuple(filename, xpath) 的列表,因此每次遇到新的单词时,只需在其列表中添加一个新的 tuple。然后,您只需遍历其中一个字典的键以在另一个字典中查找匹配项,然后在两个字典中记录元组列表。
猜你喜欢
  • 2020-07-30
  • 1970-01-01
  • 1970-01-01
  • 2013-09-13
  • 1970-01-01
  • 2019-03-16
相关资源
最近更新 更多