PHP继续爬主页

半夜看着同学新换的cnblogs,瞧了瞧主页html的内容,居然标签内容和wordpress相差甚远,显然不是一家人,不来一家模子,看着痒痒的,继续来爬一把,这次懒得用python爬,比较单调,换换口味,用好久没动过手的PHP爬一爬,其实思路大同小异,只不过处理细节差异而已

先拿自己的wordpress试试水,还是通过正则表达式找到相关分类目录行,然后截取出关键字,做起来比较简单,就直接以脚本形式写和运行,不用镶嵌到html里了

<?php
    $url = “http://lihuia.com”;
    $html = file_get_contents($url);
    $lines = explode(“\n”, $html);
    $pattern = ‘/cat-item-\d+\”><a href=\”.*\”\s*>(.*)<\/a>/’;
    for($i = 0; $i < count($lines); $i++){
        if(preg_match($pattern, $lines[$i], $title)){
            echo $title[1] . “, “;
        }
    }
?>

先获取主页内容,然后按换行将html内容分割成一个数组内容,然后遍历所有行,按照pattern进行模式匹配,输出我们所要的,唯一需要注意的是preg_match的返回值做一下判断,因为有很多无法匹配的行,会打印一些错误的

lihui@LastWish $ php lihui.php
Algorithm, Compiler, CPU, Driver, Hadoop, HTTP, Java, Json, Libpcap, Linux, Match, Network, OpenStack, Perl, PHP, Python, Sense, Shell, Struct, TCP/IP, Test, Tool, VMware, Web, 生活, 音乐

OK,接下来瞧瞧同学的这cnblogs,很容易,他的所有分类都在同一行html语句中:

<li><a href=”http://www.cnblogs.com/wanbi/tag/css/”>css</a>(10)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/jquery/”>jquery</a>(5)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/dom/”>dom</a>(4)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/html/”>html</a>(3)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/javascript/”>javascript</a>(1)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/%E5%93%8D%E5%BA%94%E5%BC%8F/”>响应式</a>(1)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/”>性能优化</a>(1)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/%E8%87%AA%E9%80%82%E5%BA%94/”>自适应</a>(1)</li>

与wordpress不同的是:

(1)假如直接wget主页的URL,仅仅下载了index的html,会没有分类信息的,需要将这个URL全部信息都另存在文件中,通过浏览器另存为HTML来处理

(2)所有标签内容全在同一行,假如他新添加分类,肯定还是接在这后面,而不是需要分多行遍历

(3)模式不太固定,很显然每个标签标题左右不一样,但这对正则表达式来说还算简单

也就是说首先得定位到这行,而且必须是独一无二,然后再来把这行进行分割,依次一个一个拔出所有的分类名

很不幸,类似<li><a href=http://www.cnblogs.com/wanbi/tag/XXX/>的模式特别的多,也就是仅仅通过这个定位就有多余的,老规矩,找差异性,但是在每个分类的后面</a>(数字)</li>,两边的反标签没啥乐不起,但是中间的数字可真的是天助我也,为什么?独一无二!!!也不知道是不是cnblogs在搭建框架的时候故意这么搭建,使得用户在添加分类的时候好找到这行,添加到后面的原因,总之,这样就手到擒来了,步骤:

(1)根据</a>(数字)</li>这个pattern定位找到分类的这行

<?php
    $html = fopen(“bibi.html”, “r”);
    $pattern = ‘/<\/a>(\(\d\))<\/li>/’;
    while(!feof($html)){
        $line = fgets($html);
        if(preg_match($pattern, $line, $title)){
            echo $line;
        }
    }
    fclose($html);
?>

运行结果,第一步这行已经定位出来了(bibi.html就是另存为的html):

lihui@LastWish $ php lihui.php
<li><a href=”http://www.cnblogs.com/wanbi/tag/css/”>css</a>(10)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/jquery/”>jquery</a>(5)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/dom/”>dom</a>(4)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/html/”>html</a>(3)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/javascript/”>javascript</a>(1)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/%E5%93%8D%E5%BA%94%E5%BC%8F/”>响应式</a>(1)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/”>性能优化</a>(1)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/%E8%87%AA%E9%80%82%E5%BA%94/”>自适应</a>(1)</li>

(2)得到了这行之后,需要进行分割,分别取出分类目录,方法就是可以观察到分类目录都是在标签</a>的前面,那么将这整行字符串按</a>分割,就会得到一个数组,每个数组元素都是以分类目录为结尾的字符串,然后将分类目录前面没用的字符串给替换成空,那么就输出来了我们所需要的分类目录信息

<?php
    $html = fopen(“bibi.html”, “r”);
    $pattern = ‘/<\/a>(\(\d\))<\/li>/’;
    while(!feof($html)){
        $line = fgets($html);
        if(preg_match($pattern, $line, $title)){
            $titles = explode(“</a>”, $line);
            for($i = 0; $i < count($titles); $i++){
                echo preg_replace(“/.*>/”, “”, $titles[$i]) . “\n”;
            }
        }
    }
    fclose($html);
?>

lihui@LastWish /cygdrive/e $ php lihui.php
css
jquery
dom
html
javascript
响应式
性能优化
自适应

刚才说过了,最后一行echo preg_replace(“/.*>/”, “”, $titles[$i]) . “\n”;其实就是做了一下替换,假如没有这行,输出结果是:

lihui@LastWish /cygdrive/e $ php lihui.php
<li><a href=”http://www.cnblogs.com/wanbi/tag/css/”>css
(10)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/jquery/”>jquery
(5)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/dom/”>dom
(4)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/html/”>html
(3)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/javascript/”>javascript
(1)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/%E5%93%8D%E5%BA%94%E5%BC%8F/”>响应式
(1)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/%E6%80%A7%E8%83%BD%E4%BC%98%E5%8C%96/”>性能优化
(1)</li><li><a href=”http://www.cnblogs.com/wanbi/tag/%E8%87%AA%E9%80%82%E5%BA%94/”>自适应
(1)</li>

所以这行意思就是以贪婪模式将包括  “>”在内的前面一部分字符串全部替换成空,自然就只剩下分类目录了

还有一点要注意的就是php在写pattern的时候,有时候要注意单引号和双引号区别,还有match和replace不同,有的需要转义而有的不需要

发表回复