• 从其他网站抓数据


    缘由

    吃饭的时候和朋友聊天,谈到他上一个项目,他去抓其他网站的数据,然后用canvas画出走势图。吸引我的是前面的抓数据,以前从来没有尝试过,一定会很有意思了!

    开始

    听他讲大致就是用jsonp去请求,然后读取json吧。感觉这种方式不太好,因为只有目标网站提供了相应接口,才能去请求,然后解析收到的数据。 自己尝试用jsonp去请求一些数据,于是找数据接口,不过好少。目前找到的下面几个: (浏览器中打开的json格式不太好看,请读者朋友把下面的json拷到http://jsonformatter.curiousconcept.com/

    朋友项目中用到的:

    http://jry.baidao.com/api/hq/npdata.do

    天气:

    http://www.weather.com.cn/data/sk/101281601.html

    http://www.weather.com.cn/data/cityinfo/101281601.html

    http://m.weather.com.cn/data/101281601.html //东莞天气

    ….

    新浪:

    https://api.weibo.com/2/statuses/public_timeline.json?source=1105337522//获取公共微博注意.最后为你的appkey。

    https://api.weibo.com/2/account/get_uid.json?source=1105337522//获取授权用户UID.

    https://api.weibo.com/2/statuses/friends_timeline.json?source=1105337522 获取当前登录用户及其所关注用户的最新微博

    https://api.weibo.com/2/statuses/user_timeline.json?source=1105337522//获取用户最新的微博

    豆瓣:

    http://api.douban.com/v2/user/freestyle21//获取用户信息

    http://api.douban.com/shuo/v2/statuses/user_timeline/freestyle21//获取用户时间线

    在用jsonp请求数据的时候,只需要把url换成上面的就可以了,然后在回调函数里面处理返回的json数据就好了。

    文章的标题叫做抓数据,但是到此为止好像只有请求数据,没有抓。。

    然后

    尽管上面找的那些链接能够完成很多事情,但是,让我不爽的是提供接口的网站并不多。要是我想要虎扑上的比赛数据呢?要是我想要河畔最新的贴子呢?

    于是,又开始在网上找可以抓取任意网站数据的方法。在一篇文章中看到了火车头采集器,去下载了。把它的论坛上三个视频看了,感觉这个只是适合站长,不太适合普通开发者。不过功能真的是比较强大。这里不讲了,有兴趣的可以从这里去看下。

    然后接着查询。。印象中python和java比较适合干这样的事,但是对这两门语言都不太熟悉,故还是想从熟悉的东西着手。咨询几个朋友,原来php也可以抓取数据~~

    查看了几个例子,自己实验了一番,总结如下。

    通过fopen来读取要抓取的网页

    下面的例子来抓取我博客的title

    <?php
        $file = fopen ("http://freestyle21.cn/", "r"); 
        if (!$file) { 
            echo "<font color=red>Unable to open remote file.</font>\n"; 
            exit; 
        } 
        while (!feof ($file)) { 
            $line = fgets ($file, 1024); 
            if (eregi ("<title>(.*)</title>", $line, $out)) { 
                $title = $out[1]; 
                echo "".$title.""; 
                break; 
            } 
        } 
        fclose($file); 
    ?>  

    获取我博客所有代码

    <?php
        $fp = fsockopen("freestyle21.cn", 80, $errno, $errstr, 30); 
        if (!$fp) { 
           echo "$errstr ($errno)<br/>\n"; 
        } else { 
           $out = "GET / HTTP/1.1\r\n"; 
           $out .= "Host: freestyle21.cn \r\n"; 
           $out .= "Connection: Close \r\n\r\n"; 
           fputs($fp, $out); 
           while (!feof($fp)) { 
             echo fgets($fp, 128); 
           } 
           fclose($fp); 
        }
    ?>

    通过curl/DOMDocument/DOMXpath抓取数据

    上面的那种方式或许还不能叫抓数据。因为对返回的HTML处理不够。 然后,我们知道在php中curl可以抓取下载html(也可以模拟登录,伪装客户端等),DOMDocument可以刚刚下载的HTML加载成DOM,DOMXPath则可以使用XPath语法进行数据的定位和采集。幸运的是,对于前端来说,三个都比较熟悉,所以就比较简单了。

    抓博客中所有的链接url

    <?php
        $target_url = "http://freestyle21.cn";
        $ch = curl_init();
    
        //执行之前,设置一些参数
        curl_setopt($ch, CURLOPT_URL,$target_url);
        curl_setopt($ch, CURLOPT_FAILONERROR, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,true);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        $html = curl_exec($ch);
    
        if (!$html) {
            echo "<br />cURL error number:" .curl_errno($ch);
            echo "<br />cURL error:" . curl_error($ch);
            exit;
        }
    
        //创建一个DomDocument对象,用于处理一个HTML
        $dom = new DOMDocument();
    
        //从一个字符串加载HTML
        @$dom->loadHTML($html);
    
        //使该HTML规范化
        $dom->normalize();
    
        //用DOMXpath加载DOM,用于查询
        $xpath = new DOMXPath($dom);
    
        //获取所有的a标签的地址
        $hrefs = $xpath->evaluate("/html/body//a//@href");
    
        for ($i = 0; $i < $hrefs->length; $i++) {
            $href = $hrefs->item($i);
            $linktext = $href->nodeValue;
            echo $linktex;
            echo "<BR>";
        }
    ?>

    结果如下;

    1

    如果想要抓取博客中的“这里记载着帅气的博主的技术成长过程,也会时而发下生活的牢骚”,这几个字,把xpath改成:

    $hrefs = $xpath->evaluate("/html/body//div//h2");

    如果想要抓取”freestyle21”几个字母,改成:

    $hrefs = $xpath->evaluate("/html/body//div//a//h1");

    如果想要抓去最下面的描述“一个老男人,今年22岁.一枚程序员,Web前端!一只科蜜,季后赛!”,改成

    $hrefs = $xpath->evaluate("/html/body//div//ul//li");

    到此,要抓取给定网页的任意数据就比较简单了,最终任务转换到解析DOM。而这,又是没有前端都擅长的~

    总结

    总的来说,用这篇文章中的方法抓取数据都不是最科学的,因为我们必须要读取所以的HTML,这样效率肯定比较低。最科学的方式还是不用下到本地服务器,直接读取。以后有需求了,还是学下Python和Java的抓取方式~~

  • 相关阅读:
    java正则表达式语法详解及其使用代码实例 (转)
    【SpringMVC学习09】SpringMVC与前台的json数据交互 (转)
    SpringMVC基于代码的配置方式(零配置,无web.xml)
    倒车入库操作要求
    R通过RJDBC连接外部数据库 (转)
    卡尔曼滤波——11.预测峰值
    卡尔曼滤波——10.均值漂移
    卡尔曼滤波——6.评估高斯分布
    神经网络入门——16实现一个反向传播
    神经网络入门——15反向传播
  • 原文地址:https://www.cnblogs.com/freestyle21/p/3076039.html
Copyright © 2020-2023  润新知