07-示例

一、抓取百度分类

  • 文档:地点检索 | 百度地图API SDK

1、获取分类

header("Content-Type:text/html;charset=utf8");
$url = 'http://lbsyun.baidu.com/index.php?title=lbscloud/poitags';

$ch = curl_init();                          // 创建一个新cURL资源
curl_setopt($ch, CURLOPT_URL, $url);         // 设置URL
curl_setopt($ch, CURLOPT_TIMEOUT, 30);      // 设置超时限制防止死循环
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// 爬取重定向页面
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);   // 自动设置Referer,防止盗链
curl_setopt($ch, CURLOPT_HEADER, 0);        // 显示返回的Header区域内容
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 要求结果保存到字符串中还是输出到屏幕上
curl_setopt($ch, CURLOPT_USERAGENT, 'Data');// 在HTTP请求中包含一个"User-Agent: "头的字符串。

$html = curl_exec($ch);                     // 运行cURL,请求URL,把结果复制给变量
if(curl_errno($ch)){
    echo 'Errno'.curl_error($curl);         //捕抓异常
}
curl_close($ch);                            // 关闭cURL连接
$preg = preg_replace("/\s/",'',$html);
preg_match_all('/(.*)<\/td>(.*)<\/td><\/tr>/Usi',$preg,$match);
$info = array_combine($match[1],$match[2]);
print_r($info);

2、创建分类表

  • Navicat for MySQL 数据库软件
CREATE TABLE `baidu_cat` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
    `pid` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '父ID',
    `name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '分类名',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3、pdo.php 公共文件

 'utf8',
		'port' => 3306,
		'type' => 'mysql',
		'host' => '127.0.0.1',
		'user' => 'root',
		'pass' => 'root',
		'name' => 'ouyangke'
	);
	$dsn = "{$db['type']}:host={$db['host']}; dbname={$db['name']}; charset={$db['charset']}; port={$db['port']}";//数据源
	try {
		//实例化PDO类,创建PDO对象
		$pdo = new PDO($dsn,$db['user'],$db['pass']);
	} catch (PDOException $e) {
		die('数据库错误:'.$e->getMessage());
	}
	return $pdo;
}
/**
* 查询多条记录
* @param $db
* @param $table
* @param $fields
* @param string $where
* @return array
*/
function select($table,$fields, $where='', $order='',$limit=''){
	//连接pdo
	$pdo = connect();
	//创建SQL语句
	$sql = 'SELECT ';
	if (is_array($fields)) {
		foreach ($fields as $field) {
			$sql .= $field.', ';
		}
	} else {
		$sql .= $fields;
	}
	$sql = rtrim(trim($sql),',');
	$sql .= '  FROM '.$table;
	//查询条件
	if(!empty($where)){
		if(is_array($where)){
			$sql .= ' WHERE ';
			foreach ($where as $k=>$v) {
				$sql .= '`'.$k.'`="'.$v.'" AND ';
			}
			$sql = substr($sql,0,strlen($sql)-5);
		}else{
			$sql .= ' WHERE '.$where;
		}
	}
	//排序条件
	if(!empty($order)) {
		$sql .= ' order by '.$order;
	}
	//分页条件
	if(!empty($limit)) {
		$sql .= ' limit '.$limit;
	}
	$sql .= ';';
	//创建PDO预处理对象
	$stmt = $pdo->prepare($sql);
	//执行查询操作
	if($stmt->execute()){
		if($stmt->rowCount()>0){
			$stmt->setFetchMode(PDO::FETCH_ASSOC);
			//返回一个二维数组
			return $stmt->fetchAll();
		}
	} else {
		return false;
	}
}
/**
* 查询单条记录
* @param $db
* @param $table   表名
* @param $fields  返回值 *
* @param string $where  条件
* @return array
*/
function find($table,$fields,$where=''){
	//连接pdo
	$pdo = connect();
	//创建SQL语句
	$sql = 'SELECT ';
	if (is_array($fields)) {
		foreach ($fields as $field) {
			$sql .= $field.', ';
		}
	} else {
		$sql .= $fields;
	}
	$sql = rtrim(trim($sql),',');
	$sql .= ' FROM '.$table;
	//查询条件
	if(!empty($where)){
		if(is_array($where)){
			$sql .= ' WHERE ';
			foreach ($where as $k=>$v) {
				$sql .= '`'.$k.'`="'.$v.'" AND ';
			}
			$sql = substr($sql,0,strlen($sql)-5);
		}else{
			$sql .= ' WHERE '.$where;
		}
	}
	$sql .= ' LIMIT 1;';
	//创建PDO预处理对象
	$stmt = $pdo->prepare($sql);
	//执行查询操作
	if($stmt->execute()){
		if($stmt->rowCount()>0){
			$stmt->setFetchMode(PDO::FETCH_ASSOC);
			return $stmt->fetch();
		}
	} else {
		return false;
	}
}
/**
* 新增数据
* @param $db
* @param $table
* @param $data
* @return bool
*/
function insert($table,$data=[]){
	//连接pdo
	$pdo = connect();
	//创建SQL语句
	$sql = "INSERT INTO {$table} SET ";
	//组装插入语句
	if(is_array($data)){
		foreach ($data as $k=>$v) {
			$sql .= $k.'="'.$v.'", ';
		}
	}else{
		return false;
	}
	//去掉尾部逗号,并添加分号结束
	$sql = rtrim(trim($sql),',').';';
	//创建PDO预处理对象
	$stmt = $pdo->prepare($sql);
	//执行新增操作
	if($stmt->execute()){
		if($stmt->rowCount()>0){
			return true;
		}
	} else {
		return false;
	}
}
/**
* 新增数据,返回新增ID
* @param $db
* @param $table
* @param $data
* @return bool
*/
function insertId($table,$data=[]){
	//连接pdo
	$pdo = connect();
	//创建SQL语句
	$sql = "INSERT INTO {$table} SET ";
	//组装插入语句
	if(is_array($data)){
		foreach ($data as $k=>$v) {
			$sql .= $k.'="'.$v.'", ';
		}
	}else{
		return false;
	}
	//去掉尾部逗号,并添加分号结束
	$sql = rtrim(trim($sql),',').';';
	//创建PDO预处理对象
	$stmt = $pdo->prepare($sql);
	//执行新增操作
	if($stmt->execute()){
		if($stmt->rowCount()>0){
			return $pdo->lastInsertId();
		}
	} else {
		return false;
	}
}
/**
* 更新数据
* @param $db
* @param $table
* @param $data
* @return bool
*/
function update($table,$data=[], $where='') {
	//连接pdo
	$pdo = connect();
	//创建SQL语句
	$sql = "UPDATE {$table} SET ";
	//组装修改语句
	if(is_array($data)){
		foreach ($data as $k=>$v) {
			$sql .= $k.'="'.$v.'", ';
		}
	}
	//去掉尾部逗号,并添加分号结束
	$sql = rtrim(trim($sql),',');
	//查询条件
	if(!empty($where)){
		$sql .= ' WHERE '.$where;
	}
	//创建PDO预处理对象
	$stmt = $pdo->prepare($sql);
	//执行新增操作
	if($stmt->execute()){
		if($stmt->rowCount()>0){
			return true;
		}
	} else {
		return false;
	}
}
/**
* 删除记录
* @param $db
* @param $table
* @param string $where
* @return bool
*/
function delete($table,$where=''){
	//连接pdo
	$pdo = connect();
	//创建SQL语句
	$sql = "DELETE FROM {$table}  ";
	//查询条件
	if(!empty($where)){
		$sql .= ' WHERE '.$where;
	}
	//创建PDO预处理对象
	$stmt = $pdo->prepare($sql);
	//执行删除操作
	if($stmt->execute()){
		if($stmt->rowCount()>0){
			return true;
		}
	} else {
		return false;
	}
}
/**
* 统计数量
* @param $pdo
* @param $table
* @param string $where
* @return number
*/
function count_num($table,$where){
	//连接pdo
	$pdo = connect();
	//创建SQL语句
	$sql  = 'SELECT count(*) as count_number FROM '.$table;
	//查询条件
	if(!empty($where)){
		$sql .= ' WHERE '.$where;
	}
	//创建PDO预处理对象
	$stmt = $pdo->prepare($sql);
	//执行查询操作
	if($stmt->execute()){
		if($stmt->rowCount()>0){
			$row  = $stmt->fetch(PDO::FETCH_ASSOC);
			$rows = $row['count_number'];
			return $rows;
		}
	} else {
		return false;
	}
}

4、保存分类

# 引入pdo公用文件
require 'pdo.php';
# 循环获取到的数据
foreach ($info as $k => $v) {
    # 整理数据
    $data = [
        'name' => $k
    ];
    # 插入一级分类
    $id = insertId('baidu_cat',$data);
    # 分割二级分类
    $two = explode('、', $v);
    # 循环二级分类
    foreach($two as $kk => $vv){
        # 整理数据
        $data = [
            'pid' => $id,
            'name' => $vv
        ];
        # 插入二级分类
        $insert = insert('baidu_cat',$data);
    }
}
echo '抓取成功';

5、逻辑

# 引入pdo公用文件
require 'pdo.php';
# 循环获取到的数据
foreach ($info as $k => $v) {
    # 整理数据
    $data = [
        'name' => $k
    ];
    # 查询一级分类是否存在
    $find = find('baidu_cat','*',$data);
    if(empty($find)){
        # 插入一级分类
        $id = insertId('baidu_cat',$data);
    }else{
        $id = $find['id'];
    }
    # 分割二级分类
    $two = explode('、', $v);
    # 循环二级分类
    foreach($two as $kk => $vv){
        # 整理数据
        $data = [
            'pid' => $id,
            'name' => $vv
        ];
        # 查询二级分类是否存在
        $find = find('baidu_cat','*',$data);
        if(empty($find)){
            # 插入二级分类
            $insert = insert('baidu_cat',$data);
        }
    }
}
echo '抓取成功';

6、日志

# 引入pdo公用文件
require 'pdo.php';
# 日志变量
$msg = '';
foreach ($info as $k => $v) {
    # 整理数据
    $data = [
        'name' => $k
    ];
    $find = find('baidu_cat','*',$data);
    # 查询一级分类是否存在
    if(empty($find)){
        # 插入一级分类
        $id = insertId('baidu_cat',$data);
        # 一级分类添加成功记录
        $msg .= '一级分类已添加,ID:'.$id.',分类名:'.$k.'
'; }else{ # 获取已存在的分类ID $id = $find['id']; # 一级分类添加失败记录 $msg .= '一级分类已存在,ID:'.$id.',分类名:'.$k.'
'; } # 分割二级分类 $two = explode('、', $v); # 循环二级分类 foreach($two as $kk => $vv){ # 整理数据 $data = [ 'pid' => $id, 'name' => $vv ]; # 查询二级分类是否存在 $find = find('baidu_cat','*',$data); if(empty($find)){ # 插入二级分类 $insert = insertId('baidu_cat',$data); # 二级分类添加成功记录 $msg .= '二级分类已添加,ID:'.$insert.',分类名:'.$vv.'
'; }else{ # 二级分类添加失败记录 $msg .= '二级分类已存在,ID:'.$find['id'].',分类名:'.$vv.'
'; } } } echo $msg;

二、抓取百度商家

  • key:u9WcDUIQLqFX3D8vNfN3hvAFiXGYueAv
  • 文档:地点检索 | 百度地图API SDK

1、获取数据

header("Content-Type:text/html;charset=utf8");
$url = 'http://api.map.baidu.com/place/v2/search?ak=1PQvdVNrRaLeCbkVB9VbZoQ9RyGFy7Kq&scope=2&output=json&query=美食®ion=合肥&page_size=20&page_num=1';

$ch = curl_init();                          // 创建一个新cURL资源
curl_setopt($ch, CURLOPT_URL, $url);        // 设置URL
curl_setopt($ch, CURLOPT_TIMEOUT, 30);      // 设置超时限制防止死循环
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);// 爬取重定向页面
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);   // 自动设置Referer,防止盗链
curl_setopt($ch, CURLOPT_HEADER, 0);        // 显示返回的Header区域内容
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);// 要求结果保存到字符串中还是输出到屏幕上
curl_setopt($ch, CURLOPT_USERAGENT, 'Data');// 在HTTP请求中包含一个"User-Agent: "头的字符串。

$html = curl_exec($ch);                     // 运行cURL,请求URL,把结果复制给变量
if(curl_errno($ch)){
    echo 'Errno'.curl_error($curl);         //捕抓异常
}
curl_close($ch);                            // 关闭cURL连接
print_r($html);

2、数据库

CREATE TABLE `baidu_shop` (
    `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
    `name` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '店铺名',
    `province` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '省',
    `city` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '市',
    `area` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '区',
    `address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '地址',
    `telephone` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '店铺电话',
    `tag` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '分类',
    `detail_url` varchar(300) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '来源url',
    `lng` decimal(10,6) DEFAULT NULL COMMENT '经度',
    `lat` decimal(10,6) DEFAULT NULL COMMENT '纬度',
    PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

3、存入数据

# 引入pdo公用文件
require 'pdo.php';
# 判断是否有数据
if(!empty($html['results'])){
	# 循环获取到的数据
	foreach ($html['results'] as $k => $v) {
		# 整理数据
		$data = [
			'name' => $v['name'],
			'province' => $v['province'],
			'city' => $v['city'],
			'area' => $v['area'],
			'address' => $v['address'],
			'telephone' => $v['telephone'],
			'tag' => $v['detail_info']['tag'],
			'detail_url' => $v['detail_info']['detail_url'],
			'lng' => $v['location']['lng'],
			'lat' => $v['location']['lat']
		];
		# 插入数据
		$id = insertId('baidu_shop',$data);
	}
}
echo '抓取成功';

4、逻辑、日志

# 引入pdo公用文件
require 'pdo.php';
# 日志变量
$msg = '';
# 判断是否有数据
if(!empty($html['results'])){
	# 循环获取到的数据
	foreach ($html['results'] as $k => $v) {
		# 判断经纬度是否存在
		$find = find('baidu_shop','*',['lng'=>$v['location']['lng'],'lat'=>$v['location']['lat']]);
		# 如果存在,跳出这一次循环,并记录
		if($find){
			$msg .= ''.$v['name'].'已存在,ID为:'.$find['id'].'
'; continue; } # 整理数据 $data = [ 'name' => $v['name'], 'province' => $v['province'], 'city' => $v['city'], 'area' => $v['area'], 'address' => $v['address'], 'telephone' => $v['telephone'], 'tag' => $v['detail_info']['tag'], 'detail_url' => $v['detail_info']['detail_url'], 'lng' => $v['location']['lng'], 'lat' => $v['location']['lat'] ]; # 插入数据 $id = insertId('baidu_shop',$data); # 插入成功记录 if($id){ $msg .= ''.$v['name'].'添加成功,ID为:'.$id.'
'; }else{ $msg .= ''.$v['name'].'添加失败
'; } } } echo $msg;

5、分类处理

增加 2 个字段,存储分类

ALTER TABLE `baidu_shop`
ADD COLUMN `cat_one` int(10) UNSIGNED NULL DEFAULT 0 COMMENT '一级分类' AFTER `lat`,
ADD COLUMN `cat_two` int(10) UNSIGNED NULL DEFAULT 0 COMMENT '二级分类' AFTER `cat_one`;
# 循环获取到的数据
foreach ($html['results'] as $k => $v) {
	# 判断经纬度是否存在
	$find = find('baidu_shop','*',['lng'=>$v['location']['lng'],'lat'=>$v['location']['lat']]);
	# 如果存在,跳出这一次循环,并记录
	if($find){
		$msg .= ''.$v['name'].'已存在,ID为:'.$find['id'].'
'; continue; } # 分割 获取标签 $tag = explode(';',$v['detail_info']['tag']); # 获取一级分类ID $cat_one = find('baidu_cat','*',['name'=>$tag[0]]); # 获取二级分类ID $cat_two = find('baidu_cat','*',['name'=>$tag[1]]); # 整理数据 $data = [ 'name' => $v['name'], 'province' => $v['province'], 'city' => $v['city'], 'area' => $v['area'], 'address' => $v['address'], 'telephone' => isset($v['telephone'])?$v['telephone']:'', 'tag' => $v['detail_info']['tag'], 'detail_url' => $v['detail_info']['detail_url'], 'lng' => $v['location']['lng'], 'lat' => $v['location']['lat'], 'cat_one' => isset($cat_one['id'])?$cat_one['id']:0, 'cat_two' => isset($cat_two['id'])?$cat_two['id']:0 ]; # 插入数据 $id = insertId('baidu_shop',$data); # 插入成功记录 if($id){ $msg .= ''.$v['name'].'添加成功,ID为:'.$id.'
'; }else{ $msg .= ''.$v['name'].'添加失败
'; } }

6、传值

header("Content-Type:text/html;charset=utf8");
$p = isset($_GET['p'])?$_GET['p']:1;
$url = 'http://api.map.baidu.com/place/v2/search?ak=1PQvdVNrRaLeCbkVB9VbZoQ9RyGFy7Kq&scope=2&output=json&query=美食®ion=合肥&page_size=20&page_num='.$p;

备:我们使用网页可以执行,使用其他的请求方法 也能执行。但我们更需要自动执行

你可能感兴趣的:(16_PHP爬虫,数据库)