像浏览器一样检索网页内容

时间:2016-03-26 08:42:23

标签: c# .net web webclient scrapy-spider

在我学习了一些关于不同技术的东西之后,我想用UWP + NoSQL做一个小项目。我想做一个小的UWP应用程序,它抓住星座并每天早上在我的覆盆子Pi上显示它。

所以我选了一个WebClient,我做了以下事情:

WebClient client = new WebClient();
client.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2";
string downloadString = client.DownloadString("http://www.horoscope.com/us/horoscopes/general/horoscope-general-daily-today.aspx?sign=2");

但它似乎检测到这个请求不是来自浏览器,因为有趣的部分不在内容中(当我用浏览器检查时,它是在初始HTML中,根据fiddler)。

我也尝试过使用ScrapySharp,但我得到了相同的结果。知道为什么吗?

(我已经完成了UWP部分,所以我不想仅仅因为它被检测为“僵尸”而改变我个人项目的主题)

修改

似乎我不够清楚。问题是**不是*我无法解析HTML,问题是我在使用ScrapySharp / WebClient时没有收到预期的HTML

EDIT2

以下是我检索的内容:http://pastebin.com/sXi4JJRG

并且,我没有(通过示例)获得“按领域评分的星级”+每个星星的相关图像

5 个答案:

答案 0 :(得分:1)

您可以使用下面显示的代码段阅读网页的全部内容:

internal static string ReadText(string Url, int TimeOutSec)
{
    try
    {
        using (HttpClient _client = new HttpClient() { Timeout = TimeSpan.FromSeconds(TimeOutSec) })
        {
            _client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("text/html"));
            using (HttpResponseMessage _responseMsg = _client.GetAsync(Url))
            {
                using (HttpContent content = _responseMsg.Content)
                {
                    return content.ReadAsString();
                }
            }
        }
    }
    catch { throw; }
}

或者以一种简单的方式:

public static void DownloadString (string address)
{
    WebClient client = new WebClient ();
    string reply = client.DownloadString (address);

    Console.WriteLine (reply);
}

(re:https://msdn.microsoft.com/en-us/library/fhd1f0sw(v=vs.110).aspx

答案 1 :(得分:1)

是的,WebClient不会给你预期的结果。许多站点都有脚本来加载内容。所以要模拟浏览器你也应该运行页面脚本。 我从来没有做过类似的事情,所以我的回答纯粹是理论上的。

解决您需要的问题"无头浏览器"。 我知道两个项目(我从未尝试过):

http://webkitdotnet.sourceforge.net/ - 它似乎已经过时了

http://www.awesomium.com/

答案 2 :(得分:0)

前段时间我使用http://www.nrecosite.com/phantomjs_wrapper_net.aspx它效果很好,正如Anton所说,它是一个无头浏览器。也许这会有所帮助。

答案 3 :(得分:0)

我想知道是否所有有趣的部分&#39;你希望在内容中看到&#39;是图像吗?您是否知道必须单独检索任何图像? html页面包含<image.../>标签的事实也不会神奇地显示它们。正如您在Fiddler中看到的那样,在检索页面后,浏览器会检索所有图像,样式表,javascript以及指定但未包含在页面中的所有其他项目。 (您可能需要清除浏览器缓存才能看到这种情况......)

答案 4 :(得分:0)

好吧,我想我知道发生了什么:我将实际输出(没有花哨的用户代理字符串)与你的pastebin提供的输出进行比较,发现了一些有趣的东西。在第213行,您的pastebin具有:

<li class="dropdown"><a href="/us/profiles/zodiac/index-profile-zodiac-sign.aspx" class="dropdown-toggle" data-hov...ck">Forecast Tarot Readings</div>

注意接近结尾的data-hov...ck。在实际输出中,这是:

<li class="dropdown"><a href="/us/profiles/zodiac/index-profile-zodiac-sign.aspx" class="dropdown-toggle" data-hover="dropdown" data-toggle="link">Astrology</a>

接下来是大约600行代码,包括前面提到的有趣部分&#39;。在第814行,它说:

<div class="bot-explore-col-subtitle f14 blocksubtitle black">Forecast Tarot Readings</div>

,从黑色的ck开始,与pastebin输出的其余部分匹配。因此,无论是pastebin是浓缩输出还是原始输出都是。

我创建了一个新的控制台应用程序,插入了你的代码,得到了我期望的结果,包括你似乎错过的600行html:

static void Main(string[] args)
{
    WebClient client = new WebClient();
    client.Headers[HttpRequestHeader.UserAgent] = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.121 Safari/535.2";
    string downloadString = client.DownloadString("http://www.horoscope.com/us/horoscopes/general/horoscope-general-daily-today.aspx?sign=2");

    File.WriteAllText(@"D:\Temp\source-mywebclient.html", downloadString);
}

我的WebClient来自System.Net。而改变UserAgent几乎没有任何影响,一些链接有点不同。

因此,总结一下:您的问题与初始获取后动态插入的内容无关,但可能与webclient结合使用UWP。关于网站上的webclient和UWP还有另一个问题:(UWP) WebClient and downloading data from URL in表示你应该使用HttpClient。也许这是一个解决方案?