Loading... 示例 一、抓取百度分类 文档:https://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi 1、获取分类 ```php header("Content-Type:text/html;charset=utf8"); $url = 'https://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($ch); //捕抓异常 } curl_close($ch); // 关闭cURL连接 $preg = preg_replace("/\s/",'',$html); preg_match_all('/<tr><td>(.*)<\/td><td>(.*)<\/td><\/tr>/Usi',$preg,$match); $info = array_combine($match[1],$match[2]); print_r($info); ``` 2、创建分类表 Navicat for MySQL 数据库软件 ```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 公共文件 ```php <?php /** * 数据库连接 * @param $db * @return PDO */ function connect() { $db = array( 'charset' => '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公用文件 ```php require 'pdo.php'; ``` # 循环获取到的数据 ```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公用文件 ```php require 'pdo.php'; ``` # 循环获取到的数据 ```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公用文件 ```php require 'pdo.php'; ``` # 日志变量 ```php $msg = ''; foreach ($info as $k => $v) { # 整理数据 $data = [ 'name' => $k ]; $find = find('baidu_cat','*',$data); # 查询一级分类是否存在 if(empty($find)){ # 插入一级分类 $id = insertId('baidu_cat',$data); # 一级分类添加成功记录 $msg .= '<span style="color:green;">一级分类已添加,ID:'.$id.',分类名:'.$k.'</span><br/>'; }else{ # 获取已存在的分类ID $id = $find['id']; # 一级分类添加失败记录 $msg .= '<span style="color:red;">一级分类已存在,ID:'.$id.',分类名:'.$k.'</span><br/>'; } # 分割二级分类 $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 .= '<span style="color:green;">二级分类已添加,ID:'.$insert.',分类名:'.$vv.'</span><br/>'; }else{ # 二级分类添加失败记录 $msg .= '<span style="color:red;">二级分类已存在,ID:'.$find['id'].',分类名:'.$vv.'</span><br/>'; } } } echo $msg; ``` 二、抓取百度商家 key:u9WcDUIQLqFX3D8vNfN3hvAFiXGYueAv 文档:https://lbsyun.baidu.com/index.php?title=webapi/guide/webservice-placeapi 1、获取数据 ```php header("Content-Type:text/html;charset=utf8"); $url = 'https://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($ch); //捕抓异常 } curl_close($ch); // 关闭cURL连接 print_r($html); ``` 2、数据库 ```mysql 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公用文件 ```php require 'pdo.php'; ``` # 判断是否有数据 ```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公用文件 ```php require 'pdo.php'; ``` # 日志变量 ```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 .= '<span style="color:red;">'.$v['name'].'已存在,ID为:'.$find['id'].'</span><br/>'; 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 .= '<span style="color:green;">'.$v['name'].'添加成功,ID为:'.$id.'</span><br/>'; }else{ $msg .= '<span style="color:red;">'.$v['name'].'添加失败</span><br/>'; } } } echo $msg; ``` 5、分类处理 增加 2 个字段,存储分类 ```mysql 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`; ``` # 循环获取到的数据 ```php foreach ($html['results'] as $k => $v) { # 判断经纬度是否存在 $find = find('baidu_shop','*',['lng'=>$v['location']['lng'],'lat'=>$v['location']['lat']]); # 如果存在,跳出这一次循环,并记录 if($find){ $msg .= '<span style="color:red;">'.$v['name'].'已存在,ID为:'.$find['id'].'</span><br/>'; 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 .= '<span style="color:green;">'.$v['name'].'添加成功,ID为:'.$id.'</span><br/>'; }else{ $msg .= '<span style="color:red;">'.$v['name'].'添加失败</span><br/>'; } } ``` 6、传值 ```php header("Content-Type:text/html;charset=utf8"); $p = isset($_GET['p'])?$_GET['p']:1; $url = 'https://api.map.baidu.com/place/v2/search?ak=1PQvdVNrRaLeCbkVB9VbZoQ9RyGFy7Kq&scope=2&output=json&query=美食®ion=合肥&page_size=20&page_num='.$p; ``` > 备:我们使用网页可以执行,使用其他的请求方法 也能执行。但我们更需要自动执行 7、curl_ssl相关参数设置 ```php curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); // 设置为 1 是检查服务器SSL证书中是否存在一个公用名(common name)。译者注:公用名(Common Name)一般来讲就是填写你将要申请SSL证书的域名 (domain)或子域名(sub domain)。 设置成 2,会检查公用名是否存在,并且是否与提供的主机名匹配。 0 为不检查名称。 在生产环境中,这个值应该是 2(默认值)。 curl_setopt($ch, CURLOPT_SSL_FALSESTART, false); // true 开启 TLS False Start (一种 TLS 握手优化方式) curl_setopt($ch, CURLOPT_SSL_ENABLE_ALPN, false); // false 禁用 SSL 握手中的 ALPN (如果 SSL 后端的 libcurl 内建支持) 用于协商到 http2。 curl_setopt($ch, CURLOPT_SSL_ENABLE_NPN, false); // false 禁用 SSL 握手中的 NPN(如果 SSL 后端的 libcurl 内建支持),用于协商到 http2。 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // false 禁止 cURL 验证对等证书(peer's certificate)。要验证的交换证书可以在 CURLOPT_CAINFO 选项中设置,或在 CURLOPT_CAPATH中设置证书目录。 curl_setopt($ch, CURLOPT_SSL_VERIFYSTATUS, false); // true 验证证书状态。 ``` Last modification:January 15, 2023 © Allow specification reprint Like 如果觉得我的文章对你有用,请随意赞赏