Laravel实现网站数据爬取存库的多字段提取与分页问题求助
字段提取问题修复
你现有代码只提取了section节点的全部文本作为title,没有分别匹配对应标签,按你给出的DOM结构,直接遍历.hospitalDetails节点再分别取子标签内容即可:
- 先确认你的
Page模型的$fillable属性已添加title、state、address三个字段,避免批量赋值失败 - 字段提取逻辑修改如下:
// 遍历.hospitalDetails节点而不是下层的section $elements = $dom->find('.hospitalDetails'); $hospitals = []; foreach ($elements as $element) { // 取第一个匹配的标签内容,加trim去除多余空格 $hospital['title'] = trim($element->find('h2', 0)?->innerText() ?? ''); $hospital['state'] = trim($element->find('p', 0)?->innerText() ?? ''); $hospital['address'] = trim($element->find('span', 0)?->innerText() ?? ''); $hospitals[] = $hospital; }
上面的??为空值判断,避免某个标签不存在时抛出错误。
分页问题修复
首先确认目标网站的分页规则,绝大多数站点分页会使用page、p这类query参数,比如第一页是https://example.com/list?page=1,第二页是https://example.com/list?page=2,你可以用循环逐页爬取,直到当前页没有匹配的医院节点就终止循环:
public function handle() { $baseUrl = '你的目标列表页不带分页参数的地址'; $currentPage = 1; // 可先手动查总页数替换这里的上限,或者用死循环直到无数据退出 while (true) { $dom = \voku\helper\HtmlDomParser::file_get_html($baseUrl . '?page=' . $currentPage); $elements = $dom->find('.hospitalDetails'); // 当前页无数据直接退出循环 if (count($elements) == 0) { break; } foreach ($elements as $element) { $hospital = [ 'title' => trim($element->find('h2', 0)?->innerText() ?? ''), 'state' => trim($element->find('p', 0)?->innerText() ?? ''), 'address' => trim($element->find('span', 0)?->innerText() ?? '') ]; Page::create($hospital); } $currentPage++; // 加1秒延迟避免请求频率过高被站点封禁 sleep(1); } $this->info('爬取完成,共爬取' . ($currentPage - 1) . '页数据'); }
如果目标站分页是其他规则,比如页码在路径里,或者需要用post请求传分页参数,对应修改请求逻辑即可。
内容的提问来源于stack exchange,提问作者user14500330
相关产品推荐
相关产品推荐

