You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 02:27:00