如何使用正则表达式更正已抓取 html 中的图片链接
How to correct image links in scraped html using regex
使用 SimpleHTMLDom 抓取页面上的 HTML,但不是在网络浏览器中看到的,除非写入包含完整的 url到他们在网站上的位置,他们将缺少正确显示所需的信息。这些链接可以多种多样,有些没有前导斜杠 (/),有些则使用 (../)。所以我创建了一个脚本,希望使用正则表达式检索 (img src),然后遍历每个脚本,检查是否包含域名,如果不包含,则注入它。
$homepage = "https://example.com/";
$html = '<img class="drt" src="100.png"><img src="../101.png"><img src="/102.png"><img src="103.png">';
$check_img = preg_match_all("/<img .*?(?=src)src=\"([^\"]+)\"/si", $html, $m);
foreach ($m[1] as $img){
if (strpos($img, $homepage) == false) {
if (strpos($img, '../') !== false) {
$html = str_replace('../', $homepage, $img);
} elseif ($img[0] == '/') {
$html = str_replace('/', $homepage, $img);
} else {
$html = substr_replace($img, $homepage, 0, 0);
}
}
}
echo $html;
但它只注入最后一张图像,并且由于某种原因,html 中缺少 <>。
如果你想使用它,请使用 DOMDocument or other HTML parser (edit: you already are using SimpleHTMLDom but I'm unfamiliar with it, ),最好是长 运行,特别是如果你想调整或获取其他元素。
<?php
$homepage = "https://example.com/";
$html = '<img class="drt" src="100.png"><img src="../101.png"><img src="/102.png"><img src="103.png">';
$dom = new DOMDocument();
$dom->loadHTML($html);
foreach ($dom->getElementsByTagName('img') as $img) {
$src = $img->getAttribute('src');
if (strpos($img, '//') === false) {
$src = $homepage.basename($src);
$img->setAttribute('src', $src);
}
}
// hacky way! remove unwanted doctype ect
$ret = preg_replace('~<(?:!DOCTYPE|/?(?:html|body|head))[^>]*>\s*~i', '', $dom->saveHTML());
echo trim(str_replace('<meta http-equiv="Content-Type" content="text/html;charset=utf-8">', '', $ret));
// proper way! but you dont have correct DOM, no <body>
// remove <!DOCTYPE
//$dom->removeChild($dom->doctype);
// remove <html><body></body></html>
//$dom->replaceChild($dom->firstChild->firstChild->firstChild, $dom->firstChild);
//
//echo $dom->saveHTML();
或者使用您当前的代码产生相同的结果,但可能容易中断使用 basename() 删除 ./
和 ../
,并且可能 ../../
<?php
$homepage = "https://example.com/";
$html = '<img class="drt" src="100.png"><img src="../101.png"><img src="/102.png"><img src="103.png">';
$check_img = preg_match_all("/<img .*?(?=src)src=\"([^\"]+)\"/si", $html, $m);
foreach ($m[1] as $img){
if (strpos($img, '//') === false)
$html = str_replace($img, $homepage.basename($img), $html);
}
echo $html;
或者进行更长时间的检查,并将 $html
替换为替换后的 $src
值
<?php
$homepage = "https://example.com/";
$html = '<img class="drt" src="100.png"><img src="../101.png"><img src="/102.png"><img src="103.png">';
$check_img = preg_match_all("/<img .*?(?=src)src=\"([^\"]+)\"/si", $html, $m);
foreach ($m[1] as $img){
if (strpos($img, '//') === false) {
$old_img = $img;
if (strpos($img, '../') !== false) {
$img = str_replace('../', $homepage, $old_img);
} elseif ($img[0] == '/') {
$img = str_replace('/', $homepage, $old_img);
} else {
$img = $homepage.$old_img;
}
$html = str_replace($old_img, $img, $html);
}
}
echo $html;
全部产生相同的结果。
使用 SimpleHTMLDom 抓取页面上的 HTML,但不是在网络浏览器中看到的,除非写入包含完整的 url到他们在网站上的位置,他们将缺少正确显示所需的信息。这些链接可以多种多样,有些没有前导斜杠 (/),有些则使用 (../)。所以我创建了一个脚本,希望使用正则表达式检索 (img src),然后遍历每个脚本,检查是否包含域名,如果不包含,则注入它。
$homepage = "https://example.com/";
$html = '<img class="drt" src="100.png"><img src="../101.png"><img src="/102.png"><img src="103.png">';
$check_img = preg_match_all("/<img .*?(?=src)src=\"([^\"]+)\"/si", $html, $m);
foreach ($m[1] as $img){
if (strpos($img, $homepage) == false) {
if (strpos($img, '../') !== false) {
$html = str_replace('../', $homepage, $img);
} elseif ($img[0] == '/') {
$html = str_replace('/', $homepage, $img);
} else {
$html = substr_replace($img, $homepage, 0, 0);
}
}
}
echo $html;
但它只注入最后一张图像,并且由于某种原因,html 中缺少 <>。
如果你想使用它,请使用 DOMDocument or other HTML parser (edit: you already are using SimpleHTMLDom but I'm unfamiliar with it,
<?php
$homepage = "https://example.com/";
$html = '<img class="drt" src="100.png"><img src="../101.png"><img src="/102.png"><img src="103.png">';
$dom = new DOMDocument();
$dom->loadHTML($html);
foreach ($dom->getElementsByTagName('img') as $img) {
$src = $img->getAttribute('src');
if (strpos($img, '//') === false) {
$src = $homepage.basename($src);
$img->setAttribute('src', $src);
}
}
// hacky way! remove unwanted doctype ect
$ret = preg_replace('~<(?:!DOCTYPE|/?(?:html|body|head))[^>]*>\s*~i', '', $dom->saveHTML());
echo trim(str_replace('<meta http-equiv="Content-Type" content="text/html;charset=utf-8">', '', $ret));
// proper way! but you dont have correct DOM, no <body>
// remove <!DOCTYPE
//$dom->removeChild($dom->doctype);
// remove <html><body></body></html>
//$dom->replaceChild($dom->firstChild->firstChild->firstChild, $dom->firstChild);
//
//echo $dom->saveHTML();
或者使用您当前的代码产生相同的结果,但可能容易中断使用 basename() 删除 ./
和 ../
,并且可能 ../../
<?php
$homepage = "https://example.com/";
$html = '<img class="drt" src="100.png"><img src="../101.png"><img src="/102.png"><img src="103.png">';
$check_img = preg_match_all("/<img .*?(?=src)src=\"([^\"]+)\"/si", $html, $m);
foreach ($m[1] as $img){
if (strpos($img, '//') === false)
$html = str_replace($img, $homepage.basename($img), $html);
}
echo $html;
或者进行更长时间的检查,并将 $html
替换为替换后的 $src
值
<?php
$homepage = "https://example.com/";
$html = '<img class="drt" src="100.png"><img src="../101.png"><img src="/102.png"><img src="103.png">';
$check_img = preg_match_all("/<img .*?(?=src)src=\"([^\"]+)\"/si", $html, $m);
foreach ($m[1] as $img){
if (strpos($img, '//') === false) {
$old_img = $img;
if (strpos($img, '../') !== false) {
$img = str_replace('../', $homepage, $old_img);
} elseif ($img[0] == '/') {
$img = str_replace('/', $homepage, $old_img);
} else {
$img = $homepage.$old_img;
}
$html = str_replace($old_img, $img, $html);
}
}
echo $html;
全部产生相同的结果。