美文网首页
Guzzle爬取京东数据

Guzzle爬取京东数据

作者: 无聊的电风扇 | 来源:发表于2018-11-14 22:41 被阅读0次

1. 下载guzzle

打开链接 php组件下载 搜索Guzzle

packagist.org
点开第一个,复制composer命令
composer require guzzlehttp/guzzle
然后就等他下载,一般很快,慢的话先把composer换成中国镜像
omposer config repo.packagist composer https://packagist.phpcomposer.com
下载完成后会在你的目录中出现vendor目录,打开应该有这三个目录 vendor目录

composer下载会把依赖包也一并下载下来,然后我们回到vendor同级目录,创建一个文件开始写代码

2. 引入类文件,简单请求

    //引入
    require './vendor/autoload.php';
    use GuzzleHttp\Client;
    $client = new Client();
    //GET方式请求链接
    $response = $client->request('GET','http://www.baidu.com');

而后获取该链接返回结果,直接输出

    //获取html代码
    $html = $response->getBody()->getContents();
    echo $html;

可以看到我访问的是我本地的PHP文件,但返回的是百度的页面


2.php

但是要注意,这样返回的结果就是你在该链接右键查看网站源代码所获得的代码,后期用js加载出来的内容你并不能直接获取

3. 获取单个商品信息

好了,既然已经可以获取到网站的代码了,那么我们就只需要把自己需要的内容拿出来就OK了,比如我们随便打开一个京东的商品详情页


京东商品详情

我们按照前面的方式,复制url,获取该链接的html

    $response = $client->request('GET','https://item.jd.com/100000287117.html');
    $html = $response->getBody()->getContents();

现在我们从获取到的结果中用正则匹配出自己所需的内容

比如先获取一个商品名

F12 查看标题内容 复制出自己所需内容,去网页源代码中寻找有特点,容易匹配的区域


京东商品名 源代码筛选

复制该区域内容,去处理正则

  //括号区域是我们所需内容 尖括号内是别名
  $ptn_name = '/<div class="sku-name">(?<name>.*)<\/div>/isU';
  //从$html中匹配出所需内容,放入$res中
  preg_match($ptn_name,$html,$res);
  echo $res['name'];

输出结果,可以看到匹配到了需要的内容,但是乱码,肯定是字符集的问题


乱码商品名

看一下京东的字符集,是GBK,那我们在用函数转成UTF-8

  //转字符集
  echo iconv('GBK','UTF-8',$res['name']);
正常商品名

再获取一个商品图

还按照前面的方法

    $ptn_pic = '#<li  class=\'img-hover\'><img alt=\'.*\' src=\'(?<pic>.*)\'.* width=\'54\'     height=\'54\'></li>#isU';
    preg_match($ptn_pic,$html,$res);
    echo $res['pic'];

看结果

图片获取

获取skuid

    $ptn_sku = '/<a class="follow J-follow" data-id="(?<skuid>.*)" href="#none".*/isU';
    preg_match($ptn_sku,$html,$res);
    echo $res['skuid'];

再获取一个价格

html价格

还按照前面的方式去源代码中查找


空价格

哎?我们发现源代码中的价格,是空,因为价格是后面用JS生成的,所以我们没有办法直接获取,咋办呢?现在我的方法是去页面的加载文件中找长得像生成价格的js文件或者接口,这层页面找不到就去上一层,或者别的地方找


price.js

但是怪麻烦的,我就百度了一下,就找到了这个
各大平台免费api接口(福利)
既然这样那就直接用skuid去获取一下就OK了

     $response_price = json_decode($client->request('GET','http://p.3.cn/prices/mgets?skuIds=J_'.$skuid.'&type=1')->getBody()->getContents());
     echo  $response_price[0]->p;

4. 获取数据

最后获取一下10页的内容,简单存一下

  public function get_data(){
        set_time_limit(0);
        $res = [];
        for($i = 0;$i < 10; $i++){
            $res[] = $this->get_url('https://list.jd.com/list.html?cat=9192,9196,12610&page='.$i.'&sort=sort_totalsales15_desc&trans=1&JL=6_0_0#J_main');
        }
        foreach($res AS $k => $v){
            foreach($v AS $kk => $vv){
                $res = Db::table('guzzle_jd')->insert([
                    'name' => $vv['title'],
                    'price' => $vv['price'],
                    'skuid' => $vv['skuid'],
                    'img' => $vv['pic'],
                    'talk' => $vv['talk'][0]
                ]);
            }
        }
    }

    //获取本页所有商品信息
    private function get_url($url){
        $client = new Client();
        $response = $client->request('GET',$url);
        $html = $response->getBody()->getContents();
        $ptn_url ='#<div class="p-name">.*<a target="_blank" title=".*" href="(?<url>.*)">.*</a>#isU';
        preg_match_all($ptn_url,$html,$res);
        $list = [];
        foreach($res['url'] AS $k => $v){
            $list[] = $this->get_info($v);
        }
        return $list;
    }

    //获取单个商品信息
    private function get_info($url){
        $client = new Client();
        $response = $client->request('GET',$url);

        $html = $response->getBody()->getContents();
        $ptn_name = '/<div class="item ellipsis" title="(?<title>.*)">/isU';
        preg_match($ptn_name,$html,$res);
        $goods['title'] =  iconv('GBK','UTF-8',$res['title']);

        $ptn_sku = '/<a class="follow J-follow" data-id="(?<skuid>.*)" href="#none".*/isU';
        preg_match($ptn_sku,$html,$res);
        $goods['skuid'] = $res['skuid'];

        $ptn_pic = '#<img.*width="350" data-origin="(?<pic>.*)" alt=".*"/>#isU';
        preg_match($ptn_pic,$html,$res);
        $goods['pic'] = $res['pic'];

        $pth_talk = '/<div class="comment-content">(?<talk>.*)<\/div>/isU';
        preg_match_all($pth_talk,$html,$res);
        foreach($res['talk'] as $k => $v){
            $res['talk'][$k] = iconv('GBK','UTF-8',$v);
        }
        $goods['talk'] = $res['talk'];

        $response_price = json_decode($client->request('GET','http://p.3.cn/prices/mgets?skuIds=J_'.$goods['skuid'].'&type=1')->getBody()->getContents());
        echo '<pre>';
        $goods['price'] = $response_price[0]->p;

        return $goods;
    }

于是我就获取了,震动棒~


震动棒

取价格那个玩意不能用了,我再试试换一下Referrer行不行……

相关文章

网友评论

      本文标题:Guzzle爬取京东数据

      本文链接:https://www.haomeiwen.com/subject/vujsfqtx.html