使用 goutte 从 link 清空 return
Emtpy return from link using goutte
我是运行PHP 7.3.5
和"fabpot/goutte": "^3.2"
。
我试图从 link 中抓取介绍和日期,但是,我在 return 中什么也得不到。
在下面找到我的最小可行示例:
<?php
require_once 'vendor/autoload.php';
use Goutte\Client;
$client = new Client();
$url = 'body > div.container > div > div > ul.list-group.mb-5 > a';
$intr = 'body > div:nth-child(3) > div:nth-child(2) > div > table:nth-child(10) > tbody > tr > td > div > div:nth-child(1) > div > div > div > div > table > tbody > tr > th > table:nth-child(4) > tbody > tr > td';
$dat = 'body > div:nth-child(3) > div:nth-child(2) > div > table:nth-child(10) > tbody > tr > td > div > div:nth-child(1) > div > div > div > div > table > tbody > tr > th > table:nth-child(1) > tbody > tr > td:nth-child(1)';
//arrays
$introArr = array();
$urlArr = array();
$crawler = $client->request('GET', 'https://www.morningbrew.com/daily/2019/11/07');
$intro = $crawler->filter($intr)->each(function($node) {
return $node;
});
$date = $crawler->filter($dat)->each(function($node) {
return $node->html();
});
array_push( $introArr, $intro, $date);
我想回来:
对我做错了什么有什么建议吗?
感谢您的回复!
您提供给 filter()
方法的选择器(对于 $intro
和 $date
)在文档的 DOM 树中没有指向任何内容。
首先,关于您提出的那些链式选择器的一些精确度:
$intr = 'body > div:nth-child(3) > ...';
以防万一您不知道,不必从根节点(body
标记)开始查找元素。
例如,如果我想检索 .myDiv
元素,我可以执行以下操作:
$crawler->filter('.myDiv');
DOM 解析器也可以避免您遍历所有节点以查找特定或多个元素的痛苦,无论它们在树中的哪个位置。
为了更简单,尝试尽可能少地依赖 HTML 标签来查找节点,并尽可能使用 CSS class 选择器。
工作示例:
$subCrawler = $client->request('GET', 'https://www.morningbrew.com/daily/2019/11/07');
$date = $subCrawler->filter('.pcard')
->filter('table:first-child')
->filter('td:first-child')
->text();
$text = $subCrawler->filter('.pcard')
->filter('table:nth-child(4)')
->text();
备注:
因为我们只需要一个节点,所以不需要用 each()
迭代来检索节点的内容
filter()
调用在这里被链接起来以提高可读性,但这是一个偏好问题。将所有选择器连接成一个也是有效的。
我是运行PHP 7.3.5
和"fabpot/goutte": "^3.2"
。
我试图从 link 中抓取介绍和日期,但是,我在 return 中什么也得不到。
在下面找到我的最小可行示例:
<?php
require_once 'vendor/autoload.php';
use Goutte\Client;
$client = new Client();
$url = 'body > div.container > div > div > ul.list-group.mb-5 > a';
$intr = 'body > div:nth-child(3) > div:nth-child(2) > div > table:nth-child(10) > tbody > tr > td > div > div:nth-child(1) > div > div > div > div > table > tbody > tr > th > table:nth-child(4) > tbody > tr > td';
$dat = 'body > div:nth-child(3) > div:nth-child(2) > div > table:nth-child(10) > tbody > tr > td > div > div:nth-child(1) > div > div > div > div > table > tbody > tr > th > table:nth-child(1) > tbody > tr > td:nth-child(1)';
//arrays
$introArr = array();
$urlArr = array();
$crawler = $client->request('GET', 'https://www.morningbrew.com/daily/2019/11/07');
$intro = $crawler->filter($intr)->each(function($node) {
return $node;
});
$date = $crawler->filter($dat)->each(function($node) {
return $node->html();
});
array_push( $introArr, $intro, $date);
我想回来:
对我做错了什么有什么建议吗?
感谢您的回复!
您提供给 filter()
方法的选择器(对于 $intro
和 $date
)在文档的 DOM 树中没有指向任何内容。
首先,关于您提出的那些链式选择器的一些精确度:
$intr = 'body > div:nth-child(3) > ...';
以防万一您不知道,不必从根节点(body
标记)开始查找元素。
例如,如果我想检索 .myDiv
元素,我可以执行以下操作:
$crawler->filter('.myDiv');
DOM 解析器也可以避免您遍历所有节点以查找特定或多个元素的痛苦,无论它们在树中的哪个位置。
为了更简单,尝试尽可能少地依赖 HTML 标签来查找节点,并尽可能使用 CSS class 选择器。
工作示例:
$subCrawler = $client->request('GET', 'https://www.morningbrew.com/daily/2019/11/07');
$date = $subCrawler->filter('.pcard')
->filter('table:first-child')
->filter('td:first-child')
->text();
$text = $subCrawler->filter('.pcard')
->filter('table:nth-child(4)')
->text();
备注:
因为我们只需要一个节点,所以不需要用
each()
迭代来检索节点的内容filter()
调用在这里被链接起来以提高可读性,但这是一个偏好问题。将所有选择器连接成一个也是有效的。