【问题标题】:Webscraping with Goutte and Guzzle使用 Goutte 和 Guzzle 进行网页抓取
【发布时间】:2020-10-26 15:54:18
【问题描述】:

我的控制器通过以下方法从站点获取数据:

$goutteClient = new Client();
$guzzleClient = new GuzzleClient([
   'timeout' => 60,
]);
$goutteClient->setClient($guzzleClient);
$crawler = $goutteClient->request('GET', 'https://html.duckduckgo.com/html/?q=Laravel');
$crawler->filter('.result__title .result__a')->each(function ($node) {
    dump($node->text());
});

上面的代码给了我搜索结果的内容标题。我也想得到相应搜索结果的链接。它位于result__extras__url 类中。

如何同时过滤链接和标题?还是我必须为此运行另一种方法?

【问题讨论】:

    标签: php laravel guzzle goutte


    【解决方案1】:

    尝试检查节点的属性。获得href 属性后,对其进行解析以获取 URL。

    $crawler->filter('.result__title .result__a')->each(function ($node) {
        $parts = parse_url(urldecode($node->attr('href')));
        parse_str($parts['query'], $params);
        $url = $params['uddg']; // DDG puts their masked URL and places the actual URL as a query param.
        $title = $node->text();
    });
    

    【讨论】:

    • 如何传递数据来查看? titleurl 变量只能在 each function 内部访问
    • each 回调之外声明一个数组。通过引用将其传递给each 回调。使用回调中所需的数据填充数组。
    • 是的,我做到了,但它有一些问题。我已经把它贴在这里了。 stackoverflow.com/questions/62779720/…
    • 你直接传递了数组,而不是通过引用传递它,比如... use(&$a) { ...,那么它将指向同一个数组而不是一个克隆。
    【解决方案2】:

    对于解析,我通常会这样做:

    $doc = new DOMDocument();
    $doc->loadHTML((string)$crawler->getBody());
    

    从那时起,您可以使用 DOMDocument 上的getElementsByTagName 函数进行访问。

    例如:

    $rows = $doc->getElementsByTagName('tr');
    foreach ($rows as $row) {
        $cols = $row->getElementsByTagName('td');
        $value = trim($cols->item(0)->nodeValue);
    }
    

    您可以在以下位置找到更多信息 https://www.php.net/manual/en/class.domdocument.php

    【讨论】:

    • 在哪里可以找到getElementsByTagName 函数的描述。在文档中找不到它们。需要看看还有哪些方法可用
    • 我添加了官方php文档链接
    猜你喜欢
    • 2018-10-17
    • 2018-10-23
    • 2015-11-14
    • 2014-09-22
    • 2015-09-06
    • 2019-02-12
    • 2021-09-10
    • 2020-09-13
    • 2020-08-09
    相关资源
    最近更新 更多