我正在尝试使用网站个人资料(http://about.me/fernandocaldas)中的生物和图片为我的个人网页进行网页抓取,因此每当我更改该个人资料时,我的网络简报中的内容也会这样做。
之间的期望值 <script type="text/json" class="json user" data-scope="view_profile" data-lowercase_user_name="fernandocaldas">
和
</script>
这是我的代码:
$thtml = file_get_contents('http://about.me/fernandocaldas');
$matchval = '/\<script type=\"text\/json\" class=\"json.*?>(.*?)\<\/script\>/i';
preg_match($matchval, $thtml, $match);
var_dump($match);
if($match){
echo "match!\n";
foreach($match[1] as $val)
{
echo $val."<br>";
}
}
但array(0) {}
的结果始终为var_dump
。
答案 0 :(得分:1)
正则表达式对于HTML来说永远不是一个好主意:今天正则表达式似乎有用,但明天它们会失败! 1
程序员经常会想:“为什么我必须初始化解析器,加载HTML,如果只用一行正则表达式代码就可以执行大量查询?”。答案是“为什么选择导致你走错方向的道路,虽然更短?”。
在您的情况下,使用解析器还可以缩短代码。
首先,加载HTML页面,初始化一个新的DOMDocument
对象,将HTML字符串加载到其中并初始化DOMXPath
对象(DOMXPath
允许执行复杂的HTML查询):
$dom = new DOMDocument();
libxml_use_internal_errors(1);
$dom->loadHTML( $html );
$xpath = new DOMXPath( $dom );
搜索标记为<script>
且类为“json user”的元素:
$found = $xpath->query( '//script[@class="json user"]' );
if( !$found->length ) die( 'Error retrieving JSON' );
将第一个节点(以及页面中的唯一节点)的节点值放在一个变量中(我也trim
它,但它是不必要的)并用json_decode()
解码它:
$json = trim( $found->item(0)->nodeValue );
$user = json_decode( $json );
现在,在$user
对象中,您拥有所需的所有数据。在$user->first_name
,您有自己的名字,在$user->bio
,您有自己的传记。通过print_r( $user )
,您可以显示完整的$user
结构,以了解如何访问每个元素。
1 如果HTML结构发生变化,解析器也会失败。