- 最近在做一个站群项目,目前大部分网站都会限制同ip的访问频率,当然还有其他的反爬因素,这里不做考虑.
- 正好朋友杂七杂八的有一些不同ip的服务器,于是乎可以利用起来.
- 这样就能有多个节点来抓取数据.
完整php代码
<?php
// 关闭所有错误显示
error_reporting(0);
// 定义一个名为 CrawlWebPage 的函数,用于抓取网页内容
function CrawlWebPage($url, $headers, $timeout = 3){
// 检查 $url 是否为空
if('' == $url)
return array('code'=>201,'data'=>'err');
// 使用 cURL 初始化一个会话
$ch = curl_init();
// 设置要抓取的网页的 URL。
curl_setopt($ch, CURLOPT_URL, $url);
// 设置 HTTP 头信息。
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// 设置是否输出 HTTP 头信息。值为 1 表示输出,0 表示不输出。
curl_setopt($ch, CURLOPT_HEADER, 1);
// 设置 cURL 函数执行的最长时间,单位为秒。
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
// 设置是否将抓取结果作为字符串返回。值为 1 表示返回字符串,0 表示直接输出结果。
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// 设置连接超时时间,单位为秒。
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
// 设置是否跟随 HTTP 重定向。值为 1 表示跟随,0 表示不跟随。
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
// 执行 cURL 会话并获取结果
$contents = curl_exec($ch);
// 会话的 HTTP 状态码
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$headersize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
// 获取返回的cookies
preg_match_all('/^Set-Cookie:\s*([^;]*)/mi', substr($contents, 0, $headersize), $matches);
$cookies = array();
foreach($matches[1] as $item) {
parse_str($item, $cookie);
$cookies = array_merge($cookies, $cookie);
}
// 关闭 cURL 会话
curl_close($ch);
// 返回结果
return array(
'code' =>200,
'code_url' => $code,
'data' => substr($contents, $headersize),
'ck' => json_encode($cookies)
);
}
// 检查 HTTP 请求方法是否为 POST
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
// 获取请求正文中的 JSON 数据并解码
$json = json_decode(file_get_contents('php://input'), true);
// 检查 JSON 数据中是否包含 data 字段
if (isset($json['data'])) {
// 对 data 字段进行 base64 解码并解析为数组
$data = json_decode(base64_decode($json['data']), true);
// 检查数组中是否包含 url 和 header 字段
if (isset($data['url']) && isset($data['header'])) {
// 获取 url 和 header 字段的值
$url = $data['url'];
$headers = array();
foreach ($data['header'] as $key => $value) {
$headers[] = "$key: $value";
}
// 调用 CrawlWebPage 函数抓取网页内容,并将结果进行 base64 编码后输出
echo base64_encode(json_encode(CrawlWebPage($url, $headers)));
}
}
}
流程示意图
- 这样就可以通过不同的crawl节点去并发高效率的采集数据了
- 这里为什么会来回用base64编解码,是因为我们在发送和接受的数据中如果存在一些敏感词.就会比较尴尬,碰到一些意想不到的问题.
- 当然如果在crawl节点跟目标站之间存在一些不可描述的内容,可能同样会被idc屏蔽的可能性.
- 为什么代码中不处理访问失败的情况,因为某些站点可能会存在内容正常,但是给你返回一个404的状态码,所以不如直接获取到最终内容由客户端来处理更灵活.
- 如需要更细节,代码中可以能自由更改一些功能,例如增加post数据,开关重定向,超时等.
- 注: 运行环境php7+, 在php5.3上测试有一些问题.
简单使用示例
架设节点
目标url
组合提交的数据
- 需要提交的json数据
{
"url": "https://router-network.com/tools/what-is-my-user-agent",
"header": {
"User-Agent": "Mozilla/5u_com_cn"
}
}
- base64编码后的数据,
data的值是上面的json数据base64编码的字符串
{"data": "eyJ1cmwiOiJodHRwczovL3JvdXRlci1uZXR3b3JrLmNvbS90b29scy93aGF0LWlzLW15LXVzZXItYWdlbnQiLCJoZWFkZXIiOnsiVXNlci1BZ2VudCI6Ik1vemlsbGEvNXVfY29tX2NuIn19"}
用postman访问测试
- 提交数据返回了一个base64编码字符串
- 可以使用 base64 进行解码后
- 可以使用 json工具 格式化,可以看到之前提交的 "User-Agent": "Mozilla/
5u_com_cn
"
可以看到
data
字段中则是返回的源代码, ck
字段中则是返回的cookies大功告成!
使用到的工具