像往常一样,我会说可能有类似的主题。但是我没有找到它,或者我用谷歌搜索得很糟糕。我尝试了我找到的所有东西,但我需要专门的提示或帮助。
我需要优化页面的输出及其处理(例如,查找单词并记下数字或从页面中获取数据)。但是页面是非常大的屏幕:
我不知道,也许对于一个很小的人来说,我在 2 秒内处理它,有时在 5 或 10 秒内。但它可以更快吗?并在一般情况下优化输出和处理。将来,我想做一个多线程模式,即解析几个站点。但它们也一样大。而且我不知道如何快速处理页面,或者如何获得更小的响应,但是数据会更少,我将无法解析所有内容。
现在我有List<string>
特定的单词,我检查给定页面上这些单词的数量。据我了解,如果我将这样的页面写入字符串,它就会存储在程序内存中。
这是代码:控制台应用程序。主类Program调用ServiesCheck构造函数,该构造函数接受设置(作为类的集合,1 个类 - 设置)。
new ServiesCheck(settingslist);
构造函数ServiesCheck
遍历设置(引用)并调用方法在构造函数中,我调用方法:ControlSettingsServies()
private bool ControllSettingsServies(ServiesSettings setting, CookieContainer containerCookies)
{
if (setting.oneChecked)
{
var onecheckerservies = OneCheckServies(setting.settingsCheck, containerCookies, setting.linkServis);
if (onecheckerservies.isValid)
{
Console.WriteLine("Нашел");
return true;
}
else
{
Console.WriteLine("Не нашел");
return false;
}
}
return false;
}
在该方法中,我调用 OneCheckServies(它接受我准备好的 cookie、我将处理输出的设置以及要遵循的链接)
private (bool isValid, int[] countSearch, string ResHtml) OneCheckServies(ServiesSettingCheck settingsCheck, CookieContainer containercookies, string link)s
{
var startTime = System.Diagnostics.Stopwatch.StartNew();
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(link);
request.CookieContainer = containercookies;
request.AutomaticDecompression = DecompressionMethods.GZip;
//request.Proxy = null;
HttpWebResponse response = (HttpWebResponse)request.GetResponse();
String setCookieHeader = response.Headers[HttpResponseHeader.SetCookie];
bool isSerach = false;
string responceTextHtml = "";
int[] countSerchList = new int[settingsCheck.worldSerach.Count];
using (Stream stream = response.GetResponseStream())
{
using (StreamReader reader = new StreamReader(stream))
{
string line = "";
while ((line = reader.ReadLine()) != null) {
responceTextHtml += line + "\n";
foreach (string worldS in settingsCheck.worldSerach) {
if (countSerchList[settingsCheck.worldSerach.IndexOf(worldS)] <= settingsCheck.closeFoundNum) {
if (line.Contains(worldS)) {
countSerchList[settingsCheck.worldSerach.IndexOf(worldS)] += 1;
}
}
}
}
}
}
for (int i = 0; i < countSerchList.Length; i++) {
if (countSerchList[i] > settingsCheck.closeFoundNum) {
isSerach = true;
}else {
isSerach = false;
break;
}
}
startTime.Stop();
var resultTime = startTime.Elapsed;
Console.WriteLine(String.Format("{0:00}:{1:00}:{2:00}.{3:000}",
resultTime.Hours,
resultTime.Minutes,
resultTime.Seconds,
resultTime.Milliseconds));
var result = (isSerach, countSerchList, responceTextHtml);
response.Close();
return result;
}
代码对你来说可能很糟糕,但我不能这样做,而且我不知道。
- 如何优化输出?
- 如何优化搜索?
- 如果需要,还可以进行内存优化。 或者是边际速度(从 2 到 10 秒)?
将来,我需要使用这个找到的页面进行进一步的操作。
为了使一切快速运行,您需要使用优化良好的 .NET 6 而
HttpClient
不是长期弃用的HttpWebRequest
.我将编写一个基于
HtmlAgilityPack
. 解析器的意义将是通过引用统计页面上的字数,并在控制台中显示统计结果。这就是我使用的方式
页面的重量是 278 KB,根据它在 0.335 秒内加载的浏览器。
这就是我得到的
也就是说,所有的解析工作大概花费了大约 50 毫秒。好吧,您的页面要大得多,但我相信它应该仍然可以在不到半秒的时间内完成。
从结果字典中,您已经可以选择您需要的单词。当然,您可以修改方法本身并在采样阶段过滤掉不必要的内容。我只是想展示这项技术。
当然,您可以使用它仅从文档中获取文本
doc.DocumentNode.InnerText
,但是任何动态对象(其文本可以隐藏在 JavaScript 块或 CSS 样式中的某处)都不会落入选择范围内。此外,部分处理文档可以让您不必在操作中创建大型对象,因此可以保存。但是您可以尝试删除外部foreach
并替换nodeText
为doc.DocumentNode.InnerText
顺便说一下,让我们试试
控制台输出
数字略有不同,但您决定最适合您的数字。从逻辑上讲,我更喜欢最后一个选项,而且更简单。
关于实例的创建
HttpParser
,您必须为每组 cookie 和每个代理创建自己的解析器。不要忘记在不再需要创建的实例时释放它们。要在没有代理和 cookie 的情况下工作,一个解析器就足以处理所有请求,即使您想多线程执行它们也是如此。顺便说一句,您可以在此处阅读有关异步多线程的信息。