很多时候,当我们遇到问题时,我们会遇到使用Javascript生成页面上呈现的内容的问题,因此scrapy无法为其抓取(例如,ajax请求,jQuery)
你想看看phantomjs。有这个PHP实现:
http://jonnnnyw.github.io/php-phantomjs/
如果你需要让它与PHP一起工作当然。
你可以阅读页面,然后将内容提供给Guzzle,以便使用Guzzle给你的好功能(比如搜索内容等等)。这取决于你的需求,也许你可以简单地使用dom,如下所示:
How to get element by class name?
这是一些工作代码。
$content = $this->getHeadlessReponse($url);
$this->crawler->addContent($this->getHeadlessReponse($url));
/**
* Get response using a headless browser (phantom in this case).
*
* @param $url
* URL to fetch headless
*
* @return string
* Response.
*/
public function getHeadlessReponse($url) {
// Fetch with phamtomjs
$phantomClient = PhantomClient::getInstance();
// and feed into the crawler.
$request = $phantomClient->getMessageFactory()->createRequest($url, 'GET');
/**
* @see JonnyW\PhantomJs\Http\Response
**/
$response = $phantomClient->getMessageFactory()->createResponse();
// Send the request
$phantomClient->send($request, $response);
if($response->getStatus() === 200) {
// Dump the requested page content
return $response->getContent();
}
}
使用幻像的唯一缺点是,它会比guzzle慢,但当然,你必须等待所有那些讨厌的js加载。
Guzzle(Goutte在内部使用)是一个HTTP客户端。因此,javascript内容将不会被解析或执行。驻留在请求的端点之外的Javascript文件将不会被下载。
根据您的环境,我认为可以使用PHPv8(嵌入Google V8 javascript引擎的PHP扩展)和自定义handler / middleware来执行您想要的操作。
然后,根据您的环境,使用javascript客户端简单地执行抓取可能更容易。
我建议尝试获取回复内容。将其解析(如果必须)到新的html并在初始化新的Crawler对象时将其用作$ html,之后您可以像使用任何其他Crawler对象一样使用响应中的所有数据。
$crawler = $client->submit($form);
$html = $client->getResponse()->getContent();
$newCrawler = new Crawler($html);
由于无法使用javascript,我可以建议另一个解决方案:
GOOGLE CHROME>右键>检查元素>右键>编辑为html> copy>使用复制的html
$html = $the_copied_html;
$crawler = new Crawler($html);
$data = $crawler->filter('.your-selector')->each(function (Crawler $node, $i) {
return [
'text' => $node->text()
];
});
//Do whatever you want with the $data
return $data; //type Array
这仅适用于单个作业而非自动化流程。在我的情况下,这将做到这一点。