具体实现思路:
1 首先用WebClient类下载网页源码
需要注意的:
有的网页可能下不下来,有种种原因比如需要cookie,编码问题等等
这是就要具体问题具体分析比如在头部加入cookie
webclient.Headers.Add("Cookie", cookie);
这样可能需要一些重载方法。根据需要写就可以了。
2 下一步过滤掉不必要的特殊字符,把下载下来的网页内容清干净,方便抓取(比如空格双引号)
3最后也是最重要的即从目标字符串的第begin个字符处开始,读取以 strBegin 开头,
strEnd 结束的字符串.并返回获取到的内容,如果不存在,返回空。
begin是引用类型,有可能一段网页中可能会有重复的关键词
比如<!--文章标题-->,<!--文章标题-->,如果你想对第二个文章标题里的内容
操作那么begin就派上用场了,他每次抓取完都返回抓取内容的结尾,在调用
此方法就可以得到第二个<!--文章标题-->的内容。
在抓取完的数据一般都存在数据库中,如果是一个表直接存放就可以了.
如果是两个表比如新闻名称和新闻内容分开,这是你就需要用到sql server的一个全局变量
Select @@IDENTITY;它可以标识生成记录的唯一ID。以用作插入新闻内容用。(两个表以news_id关联)
4 因为是精确抓取在程序处理的过程中要用到很多正则,比如去除连接去除括号等,这当然是简单的正则了。
(见到有高手说动态生成正则还没弄懂学习之~)
Regex pattern1 = new Regex("<a.*?</a>", RegexOptions.Singleline | RegexOptions.IgnoreCase);
Regex pattern2 = new Regex("(.*?)", RegexOptions.Singleline | RegexOptions.IgnoreCase);
newscontent = pattern1.Replace(newscontent, "");
newscontent = pattern2.Replace(newscontent, "");
程序里除了主要的方法外用得最多的就属正则表达式了,处理字符串用正则表达式那是当仁不让, 。
5 下面是抓取时一些特殊情况的处理:
6抓数据的时候可以把要抓的网站和一些关键字写入xml一边程序里直接调用
这样比较省时省力,比如:
7最后就是写入数据库了,可以以上面xml里newskey的键值插入数据库。
1 首先用WebClient类下载网页源码
public
static
string
DownLoadHtml(
string
url)
{
string output = "";
Encoding encode = Encoding.Default;
WebClient webclient = new WebClient();
try
{
webclient.Headers.Add("Referer", url);
byte[] buff = webclient.DownloadData(url);
output = encode.GetString(buff);
}
catch
{
}
return output;
}
{
string output = "";
Encoding encode = Encoding.Default;
WebClient webclient = new WebClient();
try
{
webclient.Headers.Add("Referer", url);
byte[] buff = webclient.DownloadData(url);
output = encode.GetString(buff);
}
catch
{
}
return output;
}
需要注意的:
有的网页可能下不下来,有种种原因比如需要cookie,编码问题等等
这是就要具体问题具体分析比如在头部加入cookie
webclient.Headers.Add("Cookie", cookie);
这样可能需要一些重载方法。根据需要写就可以了。
2 下一步过滤掉不必要的特殊字符,把下载下来的网页内容清干净,方便抓取(比如空格双引号)
过滤特殊字符
public static string RepalceStr(string str)
{
str = str.Replace("/r/n", "");
str = str.Replace("/"", "");
str = str.Replace(":", "");
str = str.Replace("/t", "");
str = str.Replace(" ", "");
str = str.Replace("'", "");
str = str.Replace("/r", "");
str = str.Replace("/n", "");
return str;
}
public static string RepalceStr(string str)
{
str = str.Replace("/r/n", "");
str = str.Replace("/"", "");
str = str.Replace(":", "");
str = str.Replace("/t", "");
str = str.Replace(" ", "");
str = str.Replace("'", "");
str = str.Replace("/r", "");
str = str.Replace("/n", "");
return str;
}
3最后也是最重要的即从目标字符串的第begin个字符处开始,读取以 strBegin 开头,
strEnd 结束的字符串.并返回获取到的内容,如果不存在,返回空。
public
static
string
GetHTMLContent(
string
strTarget,
string
strBegin,
string
strEnd,
ref
int
begin)
{
string result;
int posBegin, posEnd;
posBegin = strTarget.IndexOf(strBegin, begin);
if (posBegin != -1)
{
posEnd = strTarget.IndexOf(strEnd, posBegin + strBegin.Length);
if (posEnd > posBegin)
{
result = strTarget.Substring(posBegin, posEnd + strEnd.Length - posBegin);
begin = posEnd + strEnd.Length;
return result;
}
}
begin = -1;
return "";
}
需要注意的:{
string result;
int posBegin, posEnd;
posBegin = strTarget.IndexOf(strBegin, begin);
if (posBegin != -1)
{
posEnd = strTarget.IndexOf(strEnd, posBegin + strBegin.Length);
if (posEnd > posBegin)
{
result = strTarget.Substring(posBegin, posEnd + strEnd.Length - posBegin);
begin = posEnd + strEnd.Length;
return result;
}
}
begin = -1;
return "";
}
begin是引用类型,有可能一段网页中可能会有重复的关键词
比如<!--文章标题-->,<!--文章标题-->,如果你想对第二个文章标题里的内容
操作那么begin就派上用场了,他每次抓取完都返回抓取内容的结尾,在调用
此方法就可以得到第二个<!--文章标题-->的内容。
在抓取完的数据一般都存在数据库中,如果是一个表直接存放就可以了.
如果是两个表比如新闻名称和新闻内容分开,这是你就需要用到sql server的一个全局变量
Select @@IDENTITY;它可以标识生成记录的唯一ID。以用作插入新闻内容用。(两个表以news_id关联)
4 因为是精确抓取在程序处理的过程中要用到很多正则,比如去除连接去除括号等,这当然是简单的正则了。
(见到有高手说动态生成正则还没弄懂学习之~)
Regex pattern1 = new Regex("<a.*?</a>", RegexOptions.Singleline | RegexOptions.IgnoreCase);
Regex pattern2 = new Regex("(.*?)", RegexOptions.Singleline | RegexOptions.IgnoreCase);
newscontent = pattern1.Replace(newscontent, "");
newscontent = pattern2.Replace(newscontent, "");
程序里除了主要的方法外用得最多的就属正则表达式了,处理字符串用正则表达式那是当仁不让, 。
5 下面是抓取时一些特殊情况的处理:
1比如新闻只让抓当日的
static DateTime todaysdate = DateTime.Now.Date;
// date为抓取的日期
DateTime newsday = Convert.ToDateTime(date);
newsday = newsday.Date;
TimeSpan s = todaysdate - newsday;
if (s.TotalDays.ToString() == " 0 " )
{
这里干活
}
2过滤特殊字符比如url里有bbs关键字的不抓
if (newsurl.IndexOf( " bbs " ) > 0 )
{
continue;
}
3写入新闻唯一id到文件避免同一天抓两次数据引起新闻重复(再抓的时候比较就可以了)
FileStream fs = new FileStream(filepaths, FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.GetEncoding( " gb2312 " ));
sw.Flush();
sw.BaseStream.Seek( 0 , SeekOrigin.Begin);
// 唯一id
sw.Write(newsqid);
sw.Close();
static DateTime todaysdate = DateTime.Now.Date;
// date为抓取的日期
DateTime newsday = Convert.ToDateTime(date);
newsday = newsday.Date;
TimeSpan s = todaysdate - newsday;
if (s.TotalDays.ToString() == " 0 " )
{
这里干活
}
2过滤特殊字符比如url里有bbs关键字的不抓
if (newsurl.IndexOf( " bbs " ) > 0 )
{
continue;
}
3写入新闻唯一id到文件避免同一天抓两次数据引起新闻重复(再抓的时候比较就可以了)
FileStream fs = new FileStream(filepaths, FileMode.OpenOrCreate, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs, System.Text.Encoding.GetEncoding( " gb2312 " ));
sw.Flush();
sw.BaseStream.Seek( 0 , SeekOrigin.Begin);
// 唯一id
sw.Write(newsqid);
sw.Close();
6抓数据的时候可以把要抓的网站和一些关键字写入xml一边程序里直接调用
这样比较省时省力,比如:
<?
xml version="1.0" encoding="utf-8"
?>
< GetDatas >
< MyData >
< CarUrl > http://www.webhost/mysite.html </ CarUrl >
< CarFilterf > <![CDATA[ 列表页特征字符串开始 ]]> </ Filterf >
< CarFilters > <![CDATA[ 列表页特征字符串结束 ]]> </ Filters >
< CarDetailFilterf > <![CDATA[ 详情页特征字符串开始 ]]> </ CarDetailFilterf >
< CarDetailFilters > <![CDATA[ 详情页特征字符串结束 ]]> </ CarDetailFilters >
< NewsKey > 种类一 </ NewsKey >
</ MyData >
< MyData >
< CarUrl > http://www.webhost/mysite.html </ CarUrl >
< Filterf > <![CDATA[ 列表页特征字符串开始 ]]> </ CarFilterf >
< Filters > <![CDATA[ 列表页特征字符串结束 ]]> </ CarFilters >
< DetailFilterf > <![CDATA[ 详情页特征字符串开始 ]]> </ CarDetailFilterf >
< DetailFilters > <![CDATA[ 详情页特征字符串结束 ]]> </ CarDetailFilters >
< NewsKey > 种类二 </ NewsKey >
</ CarData >
< MyData >
程序里根据newskey的种类写入数据库方便调用。
< GetDatas >
< MyData >
< CarUrl > http://www.webhost/mysite.html </ CarUrl >
< CarFilterf > <![CDATA[ 列表页特征字符串开始 ]]> </ Filterf >
< CarFilters > <![CDATA[ 列表页特征字符串结束 ]]> </ Filters >
< CarDetailFilterf > <![CDATA[ 详情页特征字符串开始 ]]> </ CarDetailFilterf >
< CarDetailFilters > <![CDATA[ 详情页特征字符串结束 ]]> </ CarDetailFilters >
< NewsKey > 种类一 </ NewsKey >
</ MyData >
< MyData >
< CarUrl > http://www.webhost/mysite.html </ CarUrl >
< Filterf > <![CDATA[ 列表页特征字符串开始 ]]> </ CarFilterf >
< Filters > <![CDATA[ 列表页特征字符串结束 ]]> </ CarFilters >
< DetailFilterf > <![CDATA[ 详情页特征字符串开始 ]]> </ CarDetailFilterf >
< DetailFilters > <![CDATA[ 详情页特征字符串结束 ]]> </ CarDetailFilters >
< NewsKey > 种类二 </ NewsKey >
</ CarData >
< MyData >
程序里根据newskey的种类写入数据库方便调用。
7最后就是写入数据库了,可以以上面xml里newskey的键值插入数据库。