用HttpWebRequest采集数据,如何创建3、4个或N个线程 ,并同步把成功采集的返回数据更新到唯一的一张数据表??

m9644 2008-12-20 01:13:10

Stream stream = null;
HttpWebResponse response = null;
HttpWebRequest request = null;



request = WebRequest.Create(string.Format("http://xx.New") as HttpWebRequest;
string strPostData = "name=游客&SEX=0";
byte[] wrBuffer = Encoding.GetEncoding("gb2312").GetBytes(string.Format(strPostData));

request.Method = "POST";
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = wrBuffer.Length;
// request.Referer = string.Format("http://xx.cn/");
request.UserAgent = "MSIE 6.0";
request.Timeout = 8000;




////设置一个代理
//System.Net.WebProxy myproxy = new System.Net.WebProxy("218.63.252.219", 80);
//request.Proxy = myproxy;

stream = request.GetRequestStream();
stream.Write(wrBuffer, 0, wrBuffer.Length);
stream.Close();

response = request.GetResponse() as HttpWebResponse;
stream = response.GetResponseStream();
StreamReader sr = null;
sr = new StreamReader(stream, big5);
sr.Close();
stream.Close();




用HttpWebRequest采集数据,如何创建3、4个或N个线程 ,并同步把成功采集的返回数据更新到唯一的一张数据表??
...全文
421 14 打赏 收藏 转发到动态 举报
写回复
用AI写文章
14 条回复
切换为时间正序
请发表友善的回复…
发表回复
D__02 2010-10-15
  • 打赏
  • 举报
回复

不太懂..
flyjimi 2008-12-21
  • 打赏
  • 举报
回复

private void startThread(int threadCount)
{

for (int i = 0; i < threadCount; i++)
{
Thread t = new Thread(new ThreadStart(run));
t.Name = "Thread " + i;
t.IsBackground = true;
t.Start();
Thread.Sleep(100);
}
}
bool canceled = false;
int interval = 10000;
private void run()
{
while (!canceled)
{
//执行你的处理方法
Thread.Sleep(interval);
}
}
m9644 2008-12-21
  • 打赏
  • 举报
回复
线程里中TIMER对象么?没有发现。。惭愧。。。

怎么控制呢,大哥可否再指点一下。
m9644 2008-12-21
  • 打赏
  • 举报
回复
哈,原来这样,非常感
谢much0726 和 flyjimi 二位兄弟的耐心和及时的解答,顺祝二位新年愉快。。。
much0726 2008-12-20
  • 打赏
  • 举报
回复
线程采集应该是一个封装的对象,对象里有一个TIMER对象,并且可以提供外部属性设置它的interval,一般是每5秒一次,判断当前的时间是否为采集点的分钟,这样就可以使多个线程在不同的时刻被唤醒,其他时候一定要记得释放CPU:sleep(0),之前我以为在1分钟内应该可以采集完数据,其实,没有考虑到采集失败后的处理,最好要考虑,采集的时间跨度,比如,设置采集点为21:45-21:50,这样只要时间在这个范围内就会持续的进行判断是否采集了,如果已经采集成功也要有个标志,避免重复采集同样的数据。在异常判断方面还要有个全局时针来扫描所有的时钟是否正常,还有很多其他的因素,网络环境太复杂了,异常判断一定要靠调试积累,线程的调试大部分还是得靠日志来判断,建议在开发前选择一个比较好的日志模块,推荐企业库日志或则是log4日志,线程的异常也不是单靠日志模块可以捕捉到的,必须在每层都写好异常捕获,这很重要。如果遇到什么问题,再讨论吧。记得不要急于实现,先把采集类的因素尽可能的穷尽,可以给后期开发带来高效率和低错误率。
much0726 2008-12-20
  • 打赏
  • 举报
回复
线程池都是后台线程,
相当于
Thread t=new Thread();
t.IsBackground=true;
不需要手动停止销毁,除非你自己的方法中停止了.
如果想设置时间先后顺序,建议使用Timer来控制线程.
返回结果集的时间设置在采集之后就可以了,自己想想如果灵活的使用Timer控制就可以了。
-------------
这里提醒你一下,使用多线程做资源采集一定要注意资源的释放,否则程序运行一定时间后,占的内存会越来越大.
m9644 2008-12-20
  • 打赏
  • 举报
回复
m9644 2008-12-20
  • 打赏
  • 举报
回复

//使用线程池
for (int i = 0; i < ThreadCount; i++)
{
ThreadPool.QueueUserWorkItem(你的方法, 带的参数);
}



线程池如何设计出这样的效果??
我想灵活创建三或多个采集线程,并且按不同的时间顺序分开采集,并根据成功的返回再更新数据集合。
m9644 2008-12-20
  • 打赏
  • 举报
回复


谢谢楼上的GG。
创建多个子线程后,如何在相对应的线程号,并暂停或结束子线程的操作呢??
much0726 2008-12-20
  • 打赏
  • 举报
回复
这里写法不太好,需要修改下:

Stream stream = null;
try
{
response = request.GetResponse() as HttpWebResponse;
stream = response.GetResponseStream();
StreamReader sr = null;
sr = new StreamReader(stream, big5);
//从数据流中获得数据
string responseFromServer = reader.ReadToEnd();
finally
{
sr.Close();
stream.Close();
}


much0726 2008-12-20
  • 打赏
  • 举报
回复

//使用线程池
for (int i = 0; i < ThreadCount; i++)
{
ThreadPool.QueueUserWorkItem(你的方法, 带的参数);
}

private static object objlock;
..............
response = request.GetResponse() as HttpWebResponse;
stream = response.GetResponseStream();
StreamReader sr = null;
sr = new StreamReader(stream, big5);
//从数据流中获得数据
string responseFromServer = reader.ReadToEnd();
sr.Close();
stream.Close();

lock(objlock)
{
//写入数据表的操作
}



m9644 2008-12-20
  • 打赏
  • 举报
回复

如果想设置时间先后顺序,建议使用Timer来控制线程.
返回结果集的时间设置在采集之后就可以了,自己想想如果灵活的使用Timer控制就可以了。
-------------
这里提醒你一下,使用多线程做资源采集一定要注意资源的释放,否则程序运行一定时间后,

*************************************************************************

谢谢楼上兄弟的精确指点。
Timer怎么设计线程池的时间先后顺序呢?倘若采集需要创建四五或十来个采集对象呢?? 如何实现线程池里的时间先后??
本人是新手,恳切请其它熟手耐心指点一二。急,谢谢。



至于much0726 兄弟提到资源的释放 ,是否指


stream = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress);
StreamReader sr = null;
sr = new StreamReader(stream, big5);
while ((count = sr.Read(buffer, 0, buffer.Length)) > 0)
{

}
sr.Close();
stream.Close();

finally
{
if (response != null) response.Close();
if (request != null) request.Abort();

}

还有其它资源的释放否??
xjw163 2008-12-20
  • 打赏
  • 举报
回复
顶了
简单C#信息采集工具实现 http://blog.csdn.net/xiaoxiao108/archive/2011/06/01/6458367.aspx 最近想整只爬虫玩玩,顺便熟悉下正则表达式。 开发环境 vs2008 sql2000 实现方法如下 1.先抓取网页代码 2.通过正则匹配出你需要的内容 比如http://www.soso.com/q?w=%C4%E3%BA%C3&pg=1 页面中 搜索结果的标题跟连接地址。具体可以根据你的需要填写合适的地址跟正则。 3.把匹配出的内容保存到数据库中。对其中的数据可以根据需要自己进行处理 具体实现代码 1.读取网页的代码 public static string GetDataFromUrl(string url) { string str = string.Empty; HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url); //设置Http头; request.AllowAutoRedirect = true; request.AllowWriteStreamBuffering = true; request.Referer = ""; request.Timeout = 10 * 1000; //request.UserAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; SV1; .NET CLR 1.1.4322; .NET CLR 2.0.50727; .NET CLR 3.0.04506.648; .NET CLR 3.5.21022)"; HttpWebResponse response = null; try { response = (HttpWebResponse)request.GetResponse(); if (response.StatusCode == HttpStatusCode.OK) { //根据http应答头来判别编码 string Characterset = response.CharacterSet; Encoding encode; if (Characterset != "") { if (Characterset == "ISO-8859-1") { Characterset = "gb2312"; } encode = Encoding.GetEncoding(Characterset); } else { encode = Encoding.Default; } //声明一个内存流来贮存http应答流 Stream Receivestream = response.GetResponseStream(); MemoryStream mstream = new MemoryStream(); byte[] bf = new byte[255]; int count = Receivestream.Read(bf, 0, 255); while (count > 0) { mstream.Write(bf, 0, count); count = Receivestream.Read(bf, 0, 255); } Receivestream.Close(); mstream.Seek(0, SeekOrigin.Begin); //从内存流里读取字符串这里涉及到了编码方案 StreamReader reader = new StreamReader(mstream, encode); char[] buf = new char[1024]; count = reader.Read(buf, 0, 1024); while (count > 0) { str += new string(buf, 0, 1024); count = reader.Read(buf, 0, 1024); } reader.Close(); mstream.Close(); } } catch (Exception ex) { GetDataFromUrl(url); } finally { if (response != null) response.Close(); } return str; } 2.正则匹配的代码 public static ArrayList GetString(string reg, string content) { Regex r = new Regex(reg, RegexOptions.Compiled); MatchCollection matches = r.Matches(content); ArrayList a = new ArrayList(); foreach (Match m in matches) { string[] arr = new string[10]; arr[0] = m.Groups[1].Value; arr[1] = m.Groups[2].Value; arr[2] = m.Groups[3].Value; arr[3] = m.Groups[4].Value; arr[4] = m.Groups[5].Value; arr[5] = m.Groups[6].Value; arr[6] = m.Groups[7].Value; arr[7] = m.Groups[8].Value; arr[8] = m.Groups[9].Value; arr[9] = m.Groups[10].Value; a.Add(arr); } return a; } 3.如果抓取的页面很多 ,可以把多线程跟队列应用过来,提高抓取效率 Queue numbers = new Queue(); const int MaxCount = 5;//同时运行的最多线程数 private static object _lock = new object(); private void Test() { while (true) { int i = 0; lock (_lock) { if (numbers.Count == 0) { flag = false; return; } i = numbers.Dequeue(); } f(i); } } void Ssss() { for (int i = 1; i <= 100; i++)//处理的页面参数 从http://www.soso.com/q?w=你好&pg=1 到http://www.soso.com/q?w=你好&pg=100 { numbers.Enqueue(i); } for (int i = 0; i < MaxCount; i++) { Thread thread = new Thread(new ThreadStart(Test)); thread.Name = "T" + i.ToString(); thread.Start(); } } private void f(int num) { string str = ClassLibrary1.Class1.GetDataFromUrl("http://www.soso.com/q?w=%C4%E3%BA%C3&pg="+num); string reg = "]+? target=\"_blank\">([\\s\\S]+?)"; ArrayList a = ClassLibrary1.Class1.GetString(reg, str); for (int i = 0; i ] 除了>以为的字符 [\u4e00-\u9fa5] 汉字 6.代码只是实现了信息采集的主要功能,根据你自己的需要更换采集页面,跟合适的正则表达式后,可以根据你的需要自动进行采集,对采集到的数据,再根据你的需要自己进行处理。 7.数据库操作部分用的3层代码生成器连接地址 在 app.config中 如果你发现有什么不合理的,需要改进的地方,联系328452421@qq.com 朱晓 。相互交流 谢谢 顺便问下 有家是新泰的没,搞软件开发 地

111,130

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Creator Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧