我用C#刮擦了一个带有HTMLAgilityPack的网站,我试图打开其中的所有链接,并用相同的方法刮擦它们。 但是,当我尝试在底部调用此方法时,由于我激活了AdBlock,因此页面是从库中下载的。实际上,我找不到任何表格,下载的HTML代码显示“ ADblock found”。 这很奇怪,因为我已经在我的Google Chrome浏览器中过滤了oddsmath网站,并且可以毫无问题地下载母版页。有人遇到过这个问题吗?
这是函数,“ Console.WriteLine”仅用于测试并查看完整的HTML代码。
<div class="checkbox-password">
<div class="remember-me">
<mat-checkbox class="example-margin">Remember me</mat-checkbox>
</div>
<div>
<a routerLink="/forgotPassword" class="createAccount"
routerLinkActive="active"> Forgot Password? </a>
</div>
编辑 更深入一点,我注意到这可能不是我的应用程序问题或与Adblock相关的问题,但似乎连接到我要抓取的网站...实际上,如果您看到这样的页面:奇怪。 com / football / international / afc-champions-league-1053 /…,您可以看到内容已在浏览器中正确加载,但表在源代码中为空。为什么?是Javascript阻止了页面加载吗?
答案 0 :(得分:1)
首先:使用最适合HAP vs AngleSharp的东西,除非时间确实是应用程序中的一个因素。在这种情况下不是。
第二:使用Web调试器(例如Fiddler或Charles)来了解发出请求时的实际含义。由于您实际上并没有使用javascript或api调用创建任何html。您仅获得页面源。这就是为什么表为空的原因。它们是使用javascript生成的。
例如。我只是使用网络调试器来查看该网站对以下内容进行了api调用:
http://www.oddsmath.com/api/v1/dropping-odds.json/?sport_type=soccer&provider_id=7&cat_id=0&interval=60&sortBy=1&limit=30&language=en
然后javascript将使用此json对象创建页面的其余部分。
这将返回一个不错的json对象,该对象比使用eithr HAP或AngleSharp的导航更容易。我建议使用NewtonSoft JSON。
如果您坚持使用HtmlAgilityPack,则需要将其与Selenium结合使用。因为那样您可以等到页面完全加载后再解析HTML。
[编辑] 进一步挖掘:
Api要求获取所有联赛及其ID:
http://www.oddsmath.com/api/v1/menu-leagues.json/?language=en
仅要求亚洲冠军联赛的api:
http://www.oddsmath.com/api/v1/events-by-league.json/?language=en&country_code=GB&league_id=1053
虽然我强烈建议您在解决方案中使用API和NewtonSoft-JSON,但我将提供如何使用Selenium来完成。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HtmlAgilityPack;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium;
using System.Threading;
namespace SeleniumHap {
class Program {
static void Main(string[] args)
{
HtmlDocument doc = new HtmlDocument();
string url = "http://www.oddsmath.com/football/sweden/division-1-1195/2019-04-26/if-sylvia-vs-nykopings-bis-2858046/";
//string url = "http://www.oddsmath.com/";
FirefoxOptions options = new FirefoxOptions();
//options.AddArguments("--headless");
IWebDriver driver = new FirefoxDriver(options);
driver.Navigate().GoToUrl(url);
while (true) {
doc.LoadHtml(driver.PageSource);
HtmlNode n = doc.DocumentNode.SelectSingleNode("//table[@id='table-odds-cat-0']//*[self::th or self::td]");
if (n != null) {
n = n.SelectSingleNode(".//div[@class='live-odds-loading']");
if (n == null) {
break;
}
}
Thread.Sleep(1000);
}
Console.WriteLine("Exited loop. Meaning the page is done loading since we could get a td. A Crude method but it works");
HtmlNodeCollection tables = doc.DocumentNode.SelectNodes("//table");
foreach(HtmlNode table in tables) {
Console.WriteLine(table.GetAttributeValue("id", "No id"));
HtmlNodeCollection tableContent = table.SelectNodes(".//*[self::th or self::td]");
foreach(HtmlNode n in tableContent) {
Console.WriteLine(n.InnerHtml);
}
break;
}
Console.ReadKey();
}
}
}
如您所见,我使用Firefox作为我的驱动程序而不是chrome。使用这两种方法时,您可能必须在编辑变量'BrowserExecutableLocation'的位置编辑选项,以告知浏览器的可执行文件在哪里。 如您所见,我正在以一种粗略的方式使用while循环,以确保浏览器在继续阅读html之前完全加载了页面。