C# 我需要一个强大的网页刮库
我需要一个强大的网页刮库挖掘内容从网络。可以付费也可以免费都可以。请为我推荐一个库或更好的方法来挖掘数据并存储在我喜欢的数据库中。我已经搜索过了,但没有找到任何好的解决方案。我需要专家给我一个好建议。请帮帮我。抓取真的很容易,你只需解析你正在下载的内容并获取所有相关链接 不过,最重要的部分是处理HTML的部分。因为大多数浏览器不需要最干净(或符合标准)的HTML来呈现,所以您需要一个HTML解析器,它将能够理解并非总是格式良好的HTML 我建议您为此使用。它在处理格式不正确的HTML方面做得非常好,并且为您提供了一个简单的界面,可以使用XPath查询来获取结果文档中的节点C# 我需要一个强大的网页刮库,c#,.net,web-crawler,web-scraping,C#,.net,Web Crawler,Web Scraping,我需要一个强大的网页刮库挖掘内容从网络。可以付费也可以免费都可以。请为我推荐一个库或更好的方法来挖掘数据并存储在我喜欢的数据库中。我已经搜索过了,但没有找到任何好的解决方案。我需要专家给我一个好建议。请帮帮我。抓取真的很容易,你只需解析你正在下载的内容并获取所有相关链接 不过,最重要的部分是处理HTML的部分。因为大多数浏览器不需要最干净(或符合标准)的HTML来呈现,所以您需要一个HTML解析器,它将能够理解并非总是格式良好的HTML 我建议您为此使用。它在处理格式不正确的HTML方面做得非常
除此之外,您只需选择一个数据存储来保存处理后的数据(您可以使用任何数据库技术)和一种从web下载内容的方法,而.NET为和/类提供了两种高级机制。我的建议: 您可以四处寻找HTML解析器,然后使用它从站点解析出信息。(像)。然后,您所需要做的就是将数据以您认为合适的方式保存到数据库中 我已经做了几次我自己的刮板,它非常简单,允许您自定义保存的数据 数据挖掘工具 如果你真的只是想得到一个工具来做这件事,那么你应该没有问题 对于简单的网站(=仅限于纯html),Mechanize的工作速度非常快。对于使用Javascript、AJAX甚至Flash的网站,您需要一个真正的浏览器解决方案,如iMacros。
使用System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SoftCircuits.Parsing
{
public class HtmlTag
{
/// <summary>
/// Name of this tag
/// </summary>
public string Name { get; set; }
/// <summary>
/// Collection of attribute names and values for this tag
/// </summary>
public Dictionary<string, string> Attributes { get; set; }
/// <summary>
/// True if this tag contained a trailing forward slash
/// </summary>
public bool TrailingSlash { get; set; }
/// <summary>
/// Indicates if this tag contains the specified attribute. Note that
/// true is returned when this tag contains the attribute even when the
/// attribute has no value
/// </summary>
/// <param name="name">Name of attribute to check</param>
/// <returns>True if tag contains attribute or false otherwise</returns>
public bool HasAttribute(string name)
{
return Attributes.ContainsKey(name);
}
};
public class HtmlParser : TextParser
{
public HtmlParser()
{
}
public HtmlParser(string html) : base(html)
{
}
/// <summary>
/// Parses the next tag that matches the specified tag name
/// </summary>
/// <param name="name">Name of the tags to parse ("*" = parse all tags)</param>
/// <param name="tag">Returns information on the next occurrence of the specified tag or null if none found</param>
/// <returns>True if a tag was parsed or false if the end of the document was reached</returns>
public bool ParseNext(string name, out HtmlTag tag)
{
// Must always set out parameter
tag = null;
// Nothing to do if no tag specified
if (String.IsNullOrEmpty(name))
return false;
// Loop until match is found or no more tags
MoveTo('<');
while (!EndOfText)
{
// Skip over opening '<'
MoveAhead();
// Examine first tag character
char c = Peek();
if (c == '!' && Peek(1) == '-' && Peek(2) == '-')
{
// Skip over comments
const string endComment = "-->";
MoveTo(endComment);
MoveAhead(endComment.Length);
}
else if (c == '/')
{
// Skip over closing tags
MoveTo('>');
MoveAhead();
}
else
{
bool result, inScript;
// Parse tag
result = ParseTag(name, ref tag, out inScript);
// Because scripts may contain tag characters, we have special
// handling to skip over script contents
if (inScript)
MovePastScript();
// Return true if requested tag was found
if (result)
return true;
}
// Find next tag
MoveTo('<');
}
// No more matching tags found
return false;
}
/// <summary>
/// Parses the contents of an HTML tag. The current position should be at the first
/// character following the tag's opening less-than character.
///
/// Note: We parse to the end of the tag even if this tag was not requested by the
/// caller. This ensures subsequent parsing takes place after this tag
/// </summary>
/// <param name="reqName">Name of the tag the caller is requesting, or "*" if caller
/// is requesting all tags</param>
/// <param name="tag">Returns information on this tag if it's one the caller is
/// requesting</param>
/// <param name="inScript">Returns true if tag began, and did not end, and script
/// block</param>
/// <returns>True if data is being returned for a tag requested by the caller
/// or false otherwise</returns>
protected bool ParseTag(string reqName, ref HtmlTag tag, out bool inScript)
{
bool doctype, requested;
doctype = inScript = requested = false;
// Get name of this tag
string name = ParseTagName();
// Special handling
if (String.Compare(name, "!DOCTYPE", true) == 0)
doctype = true;
else if (String.Compare(name, "script", true) == 0)
inScript = true;
// Is this a tag requested by caller?
if (reqName == "*" || String.Compare(name, reqName, true) == 0)
{
// Yes
requested = true;
// Create new tag object
tag = new HtmlTag();
tag.Name = name;
tag.Attributes = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
}
// Parse attributes
MovePastWhitespace();
while (Peek() != '>' && Peek() != NullChar)
{
if (Peek() == '/')
{
// Handle trailing forward slash
if (requested)
tag.TrailingSlash = true;
MoveAhead();
MovePastWhitespace();
// If this is a script tag, it was closed
inScript = false;
}
else
{
// Parse attribute name
name = (!doctype) ? ParseAttributeName() : ParseAttributeValue();
MovePastWhitespace();
// Parse attribute value
string value = String.Empty;
if (Peek() == '=')
{
MoveAhead();
MovePastWhitespace();
value = ParseAttributeValue();
MovePastWhitespace();
}
// Add attribute to collection if requested tag
if (requested)
{
// This tag replaces existing tags with same name
if (tag.Attributes.ContainsKey(name))
tag.Attributes.Remove(name);
tag.Attributes.Add(name, value);
}
}
}
// Skip over closing '>'
MoveAhead();
return requested;
}
/// <summary>
/// Parses a tag name. The current position should be the first character of the name
/// </summary>
/// <returns>Returns the parsed name string</returns>
protected string ParseTagName()
{
int start = Position;
while (!EndOfText && !Char.IsWhiteSpace(Peek()) && Peek() != '>')
MoveAhead();
return Substring(start, Position);
}
/// <summary>
/// Parses an attribute name. The current position should be the first character
/// of the name
/// </summary>
/// <returns>Returns the parsed name string</returns>
protected string ParseAttributeName()
{
int start = Position;
while (!EndOfText && !Char.IsWhiteSpace(Peek()) && Peek() != '>' && Peek() != '=')
MoveAhead();
return Substring(start, Position);
}
/// <summary>
/// Parses an attribute value. The current position should be the first non-whitespace
/// character following the equal sign.
///
/// Note: We terminate the name or value if we encounter a new line. This seems to
/// be the best way of handling errors such as values missing closing quotes, etc.
/// </summary>
/// <returns>Returns the parsed value string</returns>
protected string ParseAttributeValue()
{
int start, end;
char c = Peek();
if (c == '"' || c == '\'')
{
// Move past opening quote
MoveAhead();
// Parse quoted value
start = Position;
MoveTo(new char[] { c, '\r', '\n' });
end = Position;
// Move past closing quote
if (Peek() == c)
MoveAhead();
}
else
{
// Parse unquoted value
start = Position;
while (!EndOfText && !Char.IsWhiteSpace(c) && c != '>')
{
MoveAhead();
c = Peek();
}
end = Position;
}
return Substring(start, end);
}
/// <summary>
/// Locates the end of the current script and moves past the closing tag
/// </summary>
protected void MovePastScript()
{
const string endScript = "</script";
while (!EndOfText)
{
MoveTo(endScript, true);
MoveAhead(endScript.Length);
if (Peek() == '>' || Char.IsWhiteSpace(Peek()))
{
MoveTo('>');
MoveAhead();
break;
}
}
}
}
}
使用System.Collections.Generic;
使用System.Linq;
使用系统文本;
名称空间。解析
{
公共类HtmlTag
{
///
///此标签的名称
///
公共字符串名称{get;set;}
///
///此标记的属性名称和值的集合
///
公共字典属性{get;set;}
///
///如果此标记包含尾部正斜杠,则为True
///
公共布尔跟踪斜杠{get;set;}
///
///指示此标记是否包含指定的属性。请注意
///当此标记包含属性时,即使
///属性没有值
///
///要检查的属性的名称
///如果标记包含属性,则为True;否则为false
公共布尔属性(字符串名称)
{
返回属性。ContainsKey(名称);
}
};
公共类HTMLPasser:TextParser
{
公共HTMLPasser()
{
}
公共HTMLPasser(字符串html):基(html)
{
}
///
///解析与指定标记名匹配的下一个标记
///
///要分析的标记的名称(“*”=分析所有标记)
///返回指定标记下一次出现的信息,如果未找到,则返回null
///如果分析了标记,则为True;如果到达文档末尾,则为false
public bool ParseNext(字符串名,out-HtmlTag标记)
{
//必须始终设置参数
tag=null;
//如果未指定标记,则无需执行任何操作
if(String.IsNullOrEmpty(name))
返回false;
//循环,直到找到匹配项或没有更多标记
移动到(“”);
向前移动();
}
其他的
{
bool结果,inScript;
//解析标记
结果=ParseTag(名称、参考标记、外部输入);
//因为脚本可能包含标记字符,所以我们有特殊的
//跳过脚本内容的处理
如果(题写)
MovePastScript();
//如果找到请求的标记,则返回true
如果(结果)
返回true;
}
//查找下一个标签
MoveTo(“”&&Peek()!=NullChar)
{
如果(Peek()=='/'))
{
//句柄尾部正斜杠
如果(请求)
tag.TrailingSlash=true;
向前移动();
MovePastWhitespace();
//如果这是脚本标记,则它已关闭
inScript=false;
}
其他的
{
//解析属性名
名称=(!doctype)?ParseAttributeName():ParseAttributeValue();
MovePastWhitespace();
//解析属性值
字符串值=string.Empty;
如果(Peek()='='=')
{
向前移动();
MovePastWhitespace();
value=ParseAttributeValue();
MovePastWhitespace();
}
//如果请求标记,则向集合添加属性
如果(请求)
{
//此标记替换具有相同名称的现有标记
if(tag.Attributes.ContainsKey(name))
tag.Attributes.Remove(名称);
tag.Attributes.Add(名称、值);
}
}
}
//跳过结束“>”
向前移动();
要求归还;
}
///
///解析标记名。当前位置应为第一个字符