我正在研究链接检查器,一般情况下我可以执行HEAD请求,但是有些网站似乎禁用了这个动词,所以在失败时我还需要执行一个GET请求(仔细检查链接是否真的死了)
我使用以下代码作为我的链接测试器:
public class ValidateResult
{
public HttpStatusCode? StatusCode { get; set; }
public Uri RedirectResult { get; set; }
public WebExceptionStatus? WebExceptionStatus { get; set; }
}
public ValidateResult Validate(Uri uri, bool useHeadMethod = true,
bool enableKeepAlive = false, int timeoutSeconds = 30)
{
ValidateResult result = new ValidateResult();
HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
if (useHeadMethod)
{
request.Method = "HEAD";
}
else
{
request.Method = "GET";
}
// always compress, if you get back …Run Code Online (Sandbox Code Playgroud) 我有一个.Net爬虫在用户发出请求时运行(因此,它需要很快).它实时抓取400多个链接.(这是业务问题.)
问题:我需要检测链接是否是xml(想想rss或atom feed)或html.如果链接是xml然后我继续处理,但如果链接是html我可以跳过它.通常,我有2 xml(s)和398+ html(s).目前,我有多个线程,但处理仍然很慢,通常75秒运行,10个线程用于400多个链接,或280秒运行1个线程.(我想添加更多线程,但请参见下文..)
我面临的挑战是我如下阅读流:
var request = WebRequest.Create(requestUriString: uri.AbsoluteUri);
// ....
var response = await request.GetResponseAsync();
//....
using (var reader = new StreamReader(stream: response.GetResponseStream(), encoding: encoding)) {
char[] buffer = new char[1024];
await reader.ReadAsync(buffer: buffer, index: 0, count: 1024);
responseText = new string(value: buffer);
}
// parse first byts of reasponseText to check if xml
Run Code Online (Sandbox Code Playgroud)
问题是我的优化只获得1024是没用的,因为GetResponseAsync正在下载整个流,无论如何,正如我所看到的.(我的另一个选择是查找标题ContentType,但这是非常相似的AFAIK,因为我还是得到了内容 - 如果你不建议使用OPTIONS,我到目前为止没用 - 另外xml可能是内容类型错误标记(?),我将错过一些内容.)
如果有任何我失踪的优化请帮助,因为我的想法已经用完了.
(我的确考虑通过在多个服务器上分散负载来优化这种设计,这样我就可以平衡网络与并行性,但这与目前的体系结构有一些变化,我现在无法负担这一点.)