PHP爬虫 -- 012 做业解析(把书城信息保存到数据库)

建库建表

create database bookstore character set utf8;
use bookstore;

CREATE TABLE `category` (
  `cid` int(11) NOT NULL AUTO_INCREMENT,
  `cname` varchar(255) NOT NULL,
  PRIMARY KEY (`cid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

CREATE TABLE `book` (
  `bid` int(11) NOT NULL AUTO_INCREMENT,
  `bname` varchar(255) NOT NULL,
  `bprice` varchar(10) NOT NULL,
  `bcid` int(11) NOT NULL,
  PRIMARY KEY (`bid`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
复制代码

make_txt()换成save_data(),create_category()create_book()

/* * @Description: 把整合好的数据, 写入数据库 * @param: 整合好的数组 * @return: 没有返回值 */
function save_data($data) {
    foreach ($data as $key => $value) {
        $bcid = create_category($value['category_name']);
        foreach ($value['books'] as $k => $book) {
            $bname = $book['book_name'];
            $bprice = $book['book_price'];
            create_book($bname, $bprice, $bcid);
        }
    }
}
/* * @Description:往类别表里插入数据 * @param: 类别名称 * @return: 没有返回值 */
function create_category($category_name) {
    global $con;
    $sql = "insert into category(`cname`) values(\"{$category_name}\")";
    print($sql);
    print("\n");
    mysqli_query($con, $sql);
    return mysqli_insert_id($con);
}

/* * @Description: 往图书表中插入数据 * @param: 图书名称 * @param: 图书价格 * @param: 图书的分类id * @return: 没有返回值 */
function create_book($bname, $bprice, $bcid) {
    global $con;
    $sql = "insert into book(`bname`,`bprice`,`bcid`) values(\"{$bname}\",'{$bprice}',{$bcid})";
    print($sql);
    print("\n");
    mysqli_query($con, $sql);
}
复制代码

最终效果

完整代码

<?php

/** * _ooOoo_ * o8888888o * 88" . "88 * (| -_- |) * O\ = /O * ____/`---'\____ * .' \\| |// `. * / \\||| : |||// \ * / _||||| -:- |||||- \ * | | \\\ - /// | | * | \_| ''\---/'' | | * \ .-\__ `-` ___/-. / * ___`. .' /--.--\ `. . __ * ."" '< `.___\_<|>_/___.' >'"". * | | : `- \`.;`\ _ /`;.`/ - ` : | | * \ \ `-. \_ __\ /__ _/ .-` / / * ======`-.____`-.___\_____/___.-`____.-'====== * `=---=' * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * 佛祖保佑 永无BUG */

require 'vendor/autoload.php';
use QL\QueryList;
// 生成一个querylist对象
$ql = new QueryList();
// 生成一个数据库链接
$con = mysqli_connect('localhost', 'root', 'root', 'bookstore');
/* * @Description:获取分类 * @params: 主页url * @return: 二维数组, 包括分类名称, 分类url */
function get_category($url) {
    global $ql;

    $data = $ql->get($url)->rules([
        "category_name" => ['#default > div > div > div > aside > div.side_categories > ul > li > ul > li > a', 'text'],
        "category_url" => ['#default > div > div > div > aside > div.side_categories > ul > li > ul > li > a', 'href'],
    ])->queryData();
    // 把分类的连接地址补全
    foreach ($data as $key => $value) {
        $value['category_url'] = $url . $value['category_url'];
        $data[$key] = $value;
    }
    return $data;
}

/* * @Description: 获取分类下的图书信息, 若是有下一页, 递归获取 * @param: 分类的url * @return: 二维数组, 包括图书名称, 图书价格 */
function get_book($url) {
    global $ql;
    echo $url . "\n";
    $data = $ql->get($url)->rules([
        "book_name" => ['#default > div > div > div > div > section > div:nth-child(2) > ol > li > article > h3 > a', 'title'],
        "book_price" => ['#default > div > div > div > div > section > div:nth-child(2) > ol > li> article > div.product_price > p.price_color', 'text'],
    ])->queryData();
    // 获取下一页按钮的href, 用来拼接下一页的完整url
    $next = has_next($url);
    if ($next) {
        // 生成完整url
        $tmp_arr = explode('/', $url);
        $tmp_arr[count($tmp_arr) - 1] = $next;
        $next_url = implode('/', $tmp_arr);
        // 调用get_book(), 把返回的数据和当前数据合并
        $data = array_merge($data, get_book($next_url));
    }
    return $data;
}
/* * @Description: 判断有没有下一页 * @param: 当前url * @return: 若是有返回按钮的href, 若是没有, 返回空字符串 */
function has_next($url) {
    global $ql;
    $res = $ql->get($url)->find('#default > div > div > div > div > section > div:nth-child(2) > div > ul > li.next > a')->href;
    return $res;
}
/* * @Description: 生成最终的数组 * @param: 从分类获取的数组 * @return: 最终整合了图书信息的数组 */
function make_array($data) {
    foreach ($data as $key => $value) {
        $value['books'] = get_book($value['category_url']);
        $data[$key] = $value;
    }
    return $data;
}

/* * @Description: 把整合好的数据, 写入数据库 * @param: 整合好的数组 * @return: 没有返回值 */
function save_data($data) {
    foreach ($data as $key => $value) {
        $bcid = create_category($value['category_name']);
        foreach ($value['books'] as $k => $book) {
            $bname = $book['book_name'];
            $bprice = $book['book_price'];
            create_book($bname, $bprice, $bcid);
        }
    }
}
/* * @Description:往类别表里插入数据 * @param: 类别名称 * @return: 没有返回值 */
function create_category($category_name) {
    global $con;
    $sql = "insert into category(`cname`) values(\"{$category_name}\")";
    print($sql);
    print("\n");
    mysqli_query($con, $sql);
    return mysqli_insert_id($con);
}

/* * @Description: 往图书表中插入数据 * @param: 图书名称 * @param: 图书价格 * @param: 图书的分类id * @return: 没有返回值 */
function create_book($bname, $bprice, $bcid) {
    global $con;
    $sql = "insert into book(`bname`,`bprice`,`bcid`) values(\"{$bname}\",'{$bprice}',{$bcid})";
    print($sql);
    print("\n");
    mysqli_query($con, $sql);
}

// 爬取并整合数据
$data = make_array(get_category('http://books.toscrape.com/'));
// 把数据写入books.txt
save_data($data);
复制代码

下一节

相关文章
相关标签/搜索