对于C#中的Web爬虫项目,我尝试执行Javascript和Ajax来检索已爬网页面的完整页面源。
我正在使用需要有效HttpWebResponse对象的现有网络爬虫(Abot)。因此,我不能简单地使用driver.Navigate().GoToUrl()
方法来检索页面源。
抓取工具下载页面源代码,我想在源代码中执行现有的Javascript / Ajax。
在一个示例项目中,我尝试了以下内容但没有成功:
WebClient wc = new WebClient();
string content = wc.DownloadString("http://www.newegg.com/Product/Product.aspx?Item=N82E16834257697");
string tmpPath = Path.Combine(Path.GetTempPath(), "temp.htm");
File.WriteAllText(tmpPath, content);
var driverService = PhantomJSDriverService.CreateDefaultService();
var driver = new PhantomJSDriver(driverService);
driver.Navigate().GoToUrl(new Uri(tmpPath));
string renderedContent = driver.PageSource;
driver.Quit();
您需要以下nuget包来运行示例: https://www.nuget.org/packages/phantomjs.exe/ http://www.nuget.org/packages/selenium.webdriver
这里的问题是代码在GoToUrl()
停止,并且程序终止甚至没有给我driver.PageSource需要几分钟。
这样做会返回正确的HTML:
driver.Navigate().GoToUrl("http://www.newegg.com/Product/Product.aspx?Item=N82E16834257697");
string renderedContent = driver.PageSource;
但我不想两次下载数据。爬虫(Abot)下载HTML,我只想解析/渲染javascript和ajax。
谢谢!
答案 0 :(得分:2)
如果不运行它,我打赌你需要在tmpPath之前使用file:///。那就是:
WebClient wc = new WebClient();
string content = wc.DownloadString("http://www.newegg.com/Product/Product.aspx?Item=N82E16834257697");
string tmpPath = Path.Combine(Path.GetTempPath(), "temp.htm");
File.WriteAllText(tmpPath, content);
var driverService = PhantomJSDriverService.CreateDefaultService();
var driver = new PhantomJSDriver(driverService);
driver.Navigate().GoToUrl(new Uri("file:///" + tmpPath));
string renderedContent = driver.PageSource;
driver.Quit();
答案 1 :(得分:2)
您可能需要允许PhantomJS发出任意请求。如果域/协议不匹配,则会阻止请求,就像打开本地文件时一样。
var driverService = PhantomJSDriverService.CreateDefaultService();
driverService.LocalToRemoteUrlAccess = true;
driverService.WebSecurity = false; // may not be necessary
var driver = new PhantomJSDriver(driverService);
您可能需要将此与Dave Bush的解决方案结合起来:
driver.Navigate().GoToUrl(new Uri("file:///" + tmpPath));
某些资源的网址以//
开头,这意味着当浏览器检索这些资源时会使用该网页的协议。读取本地文件时,此协议为file://
,在这种情况下,不会找到这些资源。必须将协议添加到本地文件才能下载所有这些资源。
File.WriteAllText(tmpPath, content.Replace('"//', '"http://'));
从你的output可以看出你使用的是PhantomJS 1.9.8。情况可能是newly introduced bug对此类事情负责。您应该将PhantomJS 1.9.7与driverService.SslProcotol = 'tlsv1'
一起使用。
如果对同一个域执行多次此操作,则还应启用磁盘缓存。否则,每次尝试刮取资源时都会下载资源。这可以使用driverService.DiskCache = true;