【问题标题】:Crawling a website with PHP, but the website runs JS to generate markup用PHP爬取网站,但网站运行JS生成标记
【发布时间】:2018-10-09 15:33:59
【问题描述】:

过去几周我一直在进行网络爬取。 使用 PHP 库(PHP Simple DOM),我正在运行一个 php 脚本(使用终端)以从中获取一些 URL 和 JSON 一些数据。到目前为止,这一直工作得很好。

最近想扩展一个特定站点的爬取,遇到了如下问题:

与目前为止的任何其他网站不同,该网站仅呼应准系统标记服务器端,而是依赖单个 JS 脚本来构建相关的标记 onload。

显然我的 PHP 脚本无法处理这个问题(因为它没有执行 JS,因此据我所知,该网站大部分时间都是空白的),因此我无法抓取该网站,因为尚未创建内容。

我不确定如何继续。是否真的可以将我当前的 PHP 脚本转换为与该站点“兼容”,或者我是否需要换档并合并浏览器,即选择完全不同的路线?

我目前认为我需要创建在 iFrame 中打开 URL 的 html/js 站点,这样我就可以通过控制台手动运行 JS 函数来提取数据。 不过,我希望有一个更可行的方法。

谢谢,

【问题讨论】:

  • 我想这个问题对于独立开发者来说很难。 Google 不久前就教他们的爬虫运行 JS,而且他们是唯一成功的人
  • 你需要像 phantomjs 这样可以像浏览器一样加载页面的东西,那么它实际上真的很容易。但是,您将无法使用 php 执行此操作,您需要使用 node 或 python。不要被@LevitatorImbalance 评论分心,事实并非如此。
  • 您要抓取的网站必须是非javascript版本。否则,Google bot 将看不到任何有用的信息。
  • @DanielFaure nope,请参阅“Fetch as Google”功能。或者您可以在Google Page Speed 上测试网站preactjs.com,看看Google 完美呈现JS
  • @LevitatorImbalance,感谢您的建议。我必须对此进行大量研究(我仍然生活在过去)。我找到了一个执行这种爬取的付费工具,有一个非常好的介绍。看看sitebulb.com

标签: javascript php web-crawler


【解决方案1】:

当我需要报废一个网站时,我通常:

1 - 在普通浏览器(ff、chrome 等)上导航 目标 网站,同时监控/记录任何包含以下内容的 POST/GET 请求相关信息来自Developer Tools -> Network Tab
请特别注意XHR 请求,因为它们通常包含json 编码数据。
这是我制作的一个小视频来说明这一点:

https://www.youtube.com/watch?v=JbiZBGt8cos

您可以模仿之前制作的request headers(在视频中解释)并将其用于curl 请求,即:

$headers = [
    "Connection: keep-alive",
    "Accept: application/json, text/javascript, */*; q=0.01",
    "User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36",
    "DNT: 1",
    "Accept-Language: pt,en-US;q=0.9,en;q=0.8,pt-PT;q=0.7,pt-BR;q=0.6",
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://s1te.com/json_rand.php");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$server_output = curl_exec ($ch);
curl_close ($ch);
print  $server_output ;

2 - 在某些情况下,如果没有 启用 JavaScript 的客户端,就无法抓取某些 URL,当这种情况发生时,我通常使用 SeleniumChromeFirefox。您还可以使用无头浏览器PhantomJS。最新版本的GeckoDriver(由 Selenium 使用)也支持无头浏览。


我知道问题是关于 PHP,但如果 OP 需要使用 SeleniumPython 我会说更直观。基于此,这是Python 中的Selenium 示例:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

driver = webdriver.Firefox()
driver.get("http://www.python.org")
assert "Python" in driver.title
elem = driver.find_element_by_name("q")
elem.clear()
elem.send_keys("pycon")
elem.send_keys(Keys.RETURN)
assert "No results found." not in driver.page_source
driver.close()

Example Src

【讨论】:

  • 我选择了这个答案,因为即使从技术上讲,这两个答案都是正确的,但我发现这个答案更有帮助,尤其是在监控 AJAX 和捕获任何 GET / POST 服务器答案方面。
【解决方案2】:

我看到了两种可能的路径:

  • 如果构建 DOM 的 JavaScript 通过一个或多个 AJAX 调用获取数据,您不妨直接从这些 URL 中抓取数据(无论如何这往往更容易,例如,如果它与 JSON API)。

  • 模拟浏览器,例如使用硒。例如,this 文章讨论了您提到的确切挑战,并提供了使用 Selenium 和 Python 的解决方案。

【讨论】:

  • 而且 OP 还应该避免 JS 的一些可能危险的部分(假设开发人员是坏孩子,他们将while (true) {} 循环包含在他们的包中):)
  • @LevitatorImbalance 如果开发者使用这样的“陷阱”,他们的网站也将无法使用。无法检测到您是在处理自动请求还是普通用户。我从来没有见过这样的 js 陷阱。
  • @PedroLobito 入侵者通常不关心网站的可用性。 OTOH,有一些方法可以检测爬虫渲染。
  • @LevitatorImbalance "有一些检测爬虫渲染的方法",几十个,但没有一个可靠。
  • @PedroLobito 您的爬虫渲染器仍然可能不支持或不提供浏览器功能,这会导致脚本执行其他情况下不会执行的操作(例如无限循环、数百个 AJAX 请求等.)。尽可能多地沙箱和约束任何不受信任的代码始终是一个聪明的主意。
猜你喜欢
  • 2012-09-24
  • 1970-01-01
  • 1970-01-01
  • 2019-07-19
  • 2011-02-19
  • 1970-01-01
  • 2015-09-19
  • 1970-01-01
  • 2015-04-06
相关资源
最近更新 更多