如何从 MySQL table 中提取多个 HTML 标签
How can I extract multiple HTML tags from a MySQL table
我在基于 MySQL 的 CMS 中有一个 table,其中一个字段包含 CMS 网页中显示的文章文本。
一些文章包含以 HTML 'img' 标签形式嵌入文本中的图像。该字段包含的文本中可能有一张或几张图片。
我想要做的是创建一个查询,该查询将提取所有文章中所有图像的列表。我设法创建了一些代码如下:
SELECT nid,
substr(body,locate('<img', body),(locate('>',body,locate('<img', body)) - locate('<img', body))) as image,
body FROM `node_revisions` where body like '%<img%'
这似乎工作正常,但是当然它只提取第一张图像,我真的很想提取所有图像(事实上当然这通常意味着使用循环,但这似乎不可能在 MySQL).
仅供参考,有问题的 CMS 是 Drupal 6,因此字段名称和 table。然而,这实际上是一个关于 MySQL 而不是 Drupal 的问题,这就是为什么我在这里而不是在 Drupal Stackexchange 网站上提问。
如果您尝试使用 locate()、substring() 或正则表达式来解析 HTML 或 XML,您会发疯的。参见 https://blog.codinghorror.com/parsing-html-the-cthulhu-way/
我建议你使用 PHP 的 DOMDocument class:
<?php
$bodyHtml = "now is the time for all <img src='good.jpg'> men to come to the <img src='aid.jpg'> of their country";
$dom = new DOMDocument();
$dom->loadHTML($bodyHtml);
$imgs = $dom->getElementsByTagName("img");
foreach ($imgs as $img) {
print "$img->nodeName\n";
foreach ($img->attributes as $attr) {
print " $attr->name=$attr->value\n";
}
}
输出:
img
src=good.jpg
img
src=aid.jpg
使用正则表达式解析 html 永远不会 100%,您永远不会自信地获得每张图片并且格式正确,
您遇到的另一个问题是您在问题中暗示的问题。您在 node_revisions 中有一条记录可能包含 1、2 或 10,000 张图像。
在 SQL 中,您无法 return 每个图像作为查询结果中的新行,因此您必须 return 每个图像作为新列。
这意味着您实际上需要手动指定每一列:
SELECT code_to_return_img_1 as url1
,code_to_return_img_2 as url2
,code_to_return_img_3 as url3
,code_to_return_img_4 as url4
,code_to_return_img_5 as url5
,code_to_return_img_6 as url6
....
and so on
如果您知道每篇文章只有不到 20 张图片,而您没有 php/java/python 供您使用,而这只是您需要的一次性 hack 工作,那么您可以做到使用正则表达式和 SQL 但你 30 分钟的工作可能会变成 2 天的工作和爆裂的静脉。
如果 Java 是一个选项:
https://jsoup.org/
如果 Python 是一个选项:
https://docs.python.org/2/library/htmlparser.html
如果 PHP 是一个选项:
http://htmlparsing.com/php.html
$dom = new DOMDocument;
$dom->loadHTML($html);
$images = $dom->getElementsByTagName('img');
foreach ($images as $image) {
$imgurl = $image->getAttribute('src');
}
我在基于 MySQL 的 CMS 中有一个 table,其中一个字段包含 CMS 网页中显示的文章文本。
一些文章包含以 HTML 'img' 标签形式嵌入文本中的图像。该字段包含的文本中可能有一张或几张图片。
我想要做的是创建一个查询,该查询将提取所有文章中所有图像的列表。我设法创建了一些代码如下:
SELECT nid,
substr(body,locate('<img', body),(locate('>',body,locate('<img', body)) - locate('<img', body))) as image,
body FROM `node_revisions` where body like '%<img%'
这似乎工作正常,但是当然它只提取第一张图像,我真的很想提取所有图像(事实上当然这通常意味着使用循环,但这似乎不可能在 MySQL).
仅供参考,有问题的 CMS 是 Drupal 6,因此字段名称和 table。然而,这实际上是一个关于 MySQL 而不是 Drupal 的问题,这就是为什么我在这里而不是在 Drupal Stackexchange 网站上提问。
如果您尝试使用 locate()、substring() 或正则表达式来解析 HTML 或 XML,您会发疯的。参见 https://blog.codinghorror.com/parsing-html-the-cthulhu-way/
我建议你使用 PHP 的 DOMDocument class:
<?php
$bodyHtml = "now is the time for all <img src='good.jpg'> men to come to the <img src='aid.jpg'> of their country";
$dom = new DOMDocument();
$dom->loadHTML($bodyHtml);
$imgs = $dom->getElementsByTagName("img");
foreach ($imgs as $img) {
print "$img->nodeName\n";
foreach ($img->attributes as $attr) {
print " $attr->name=$attr->value\n";
}
}
输出:
img
src=good.jpg
img
src=aid.jpg
使用正则表达式解析 html 永远不会 100%,您永远不会自信地获得每张图片并且格式正确,
您遇到的另一个问题是您在问题中暗示的问题。您在 node_revisions 中有一条记录可能包含 1、2 或 10,000 张图像。 在 SQL 中,您无法 return 每个图像作为查询结果中的新行,因此您必须 return 每个图像作为新列。
这意味着您实际上需要手动指定每一列:
SELECT code_to_return_img_1 as url1
,code_to_return_img_2 as url2
,code_to_return_img_3 as url3
,code_to_return_img_4 as url4
,code_to_return_img_5 as url5
,code_to_return_img_6 as url6
....
and so on
如果您知道每篇文章只有不到 20 张图片,而您没有 php/java/python 供您使用,而这只是您需要的一次性 hack 工作,那么您可以做到使用正则表达式和 SQL 但你 30 分钟的工作可能会变成 2 天的工作和爆裂的静脉。
如果 Java 是一个选项: https://jsoup.org/
如果 Python 是一个选项: https://docs.python.org/2/library/htmlparser.html
如果 PHP 是一个选项: http://htmlparsing.com/php.html
$dom = new DOMDocument;
$dom->loadHTML($html);
$images = $dom->getElementsByTagName('img');
foreach ($images as $image) {
$imgurl = $image->getAttribute('src');
}