求教:用HttpWebRequest向谷歌提交搜索请求,大概提交32个左右就报错!

逍遥散人 2010-11-07 05:33:38
代码:
System.Net.HttpWebRequest r = (System.Net.HttpWebRequest)System.Net.HttpWebRequest.Create(url);
System.Net.CookieContainer c = new System.Net.CookieContainer();
r.CookieContainer = c;
r.KeepAlive = false;
r.ProtocolVersion = HttpVersion.Version10;

//创建请求
HttpWebResponse res = (HttpWebResponse)r.GetResponse();
Stream sr = res.GetResponseStream();
Encoding encode;
switch (res.CharacterSet.ToLower())
{
case "utf-8":
encode = System.Text.Encoding.GetEncoding("utf-8");
break;
case "gb2312":
encode = System.Text.Encoding.GetEncoding("gb2312");
break;
default:
encode = System.Text.Encoding.GetEncoding("gb2312"); //默认为中文
break;
}

StreamReader sr1 = new StreamReader(sr,encode);
content = sr1.ReadToEnd();
sr1.Close();
res.Close();

//Thread.Sleep(10000);

这段代码跑到32个左右时就报:

+ [System.Net.WebException] {"基础连接已经关闭: 接收时发生错误。"} System.Net.WebException
+ Data {System.Collections.ListDictionaryInternal} System.Collections.IDictionary {System.Collections.ListDictionaryInternal}
HelpLink null string
+ InnerException {"无法从传输连接中读取数据: 远程主机强迫关闭了一个现有的连接。。"} System.Exception {System.IO.IOException}
Message "基础连接已经关闭: 接收时发生错误。" string
Source "System" string
StackTrace " 在 System.Net.HttpWebRequest.GetResponse()\r\n 在 SearchGoogle.Form1.Start_Search(String entname, String scanid, String pripid, Int32 search_status) 位置 G:\\Work\\SearchGoogle\\SearchGoogle\\Form1.cs:行号 163" string
+ TargetSite {System.Net.WebResponse GetResponse()} System.Reflection.MethodBase {System.Reflection.RuntimeMethodInfo}

咋弄啊,这两天就要提交代码了,临了出这种问题,急死人啊?
我试过用sleep,休息20秒也不管用啊!!
求教各位高手,有解决办法么?谢谢了
...全文
511 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
NewUser2008 2010-11-08
  • 打赏
  • 举报
回复
将把有请求头设置好,好像Google请求头加了密
NewUser2008 2010-11-08
  • 打赏
  • 举报
回复
请求时间间隔太短 ,建义5000发送一次请求
deyygywxf 2010-11-08
  • 打赏
  • 举报
回复
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(mvarUrl);
request.Timeout = 20000;
//添加读写超时。
//request.ReadWriteTimeout = 20000;

WebResponse response;
try
{
response = request.GetResponse();
}
catch(Exception ee)
{
request.Abort();
request = null;
response = null;
//文件没有发现,直接返回。
if (ee.Message.Equals(m_400))
{
//说明不存在。
mvarUrl = null;
}
else
{
mvarUrl = null;
//失败,从新来过。
}
}
//若存在,则进行处理.
MemoryStream ms = new MemoryStream();
string strType = response.ContentType;

Stream ns = response.GetResponseStream();
//设置网络流超时时间.
ns.ReadTimeout = 6000;

byte[] nbytes = new byte[iLength];
int nReadSize = 1;
try
{
nReadSize = ns.Read(nbytes, 0, iLength);
while (nReadSize > 0)
{
ms.Write(nbytes, 0, nReadSize);
nReadSize = ns.Read(nbytes, 0, iLength);
}
byte[] bytes = ms.ToArray();
//说明成功。
DownComplete(mvarFileName, DownState.Complete, bytes);
ms.Close();
ms.Dispose();
ms = null;
ns.Close();
ns.Dispose();
ns = null;
request.Abort();
request = null;
response.Close();
response = null;
System.Threading.Thread.CurrentThread.Abort();
bytes = null;
}
catch// (Exception eeWeb)
{
//关闭。
ms.Close();
ns.Close();
//触发下载失败事件。
mvarUrl = null;
}


上述代码连接google网站没有问题。
逍遥散人 2010-11-08
  • 打赏
  • 举报
回复
试过代理,在跑到第30次的时候我就sleep,再跑的时候就自动切换代理,可还是不行
yuha1100 2010-11-08
  • 打赏
  • 举报
回复
WebProxy proxy = new WebProxy();
proxy.Address = new Uri("http://61.135.130.214:80");
request.Proxy = proxy;

g.cn搜索免费代理。 呵呵!!试试代理吧!
逍遥散人 2010-11-08
  • 打赏
  • 举报
回复
我是想要做到,提交关键字给谷歌,然后对结果进行分析,去除客户需要的信息。
现在最大的问题就是,客户的关键字是我从客户数据库中提出,非常多,因此,造成频繁访问,结果嘛......

小结一下目前的状况:每次跑32个会被封掉,用sleep到5分钟仍不起作用,但是,如果被封了后,关闭程序,等待1~2分钟后再启程序又可以跑32个.......

因为在程序中必须启用cookie,否则报错,所以,怀疑最大问题就在这儿,用httprequest.close并没有清除掉cookie,现在问题是我不知道怎么才能清除生成的CookieContainer?
逍遥散人 2010-11-08
  • 打赏
  • 举报
回复
我不可能要求用户时时刻刻更换代理啊....我就纳闷了,北京联通1、北京联通2、北京联通3这样的关键字不封,没有规律的关键字倒封得很勤啊
phil999 2010-11-08
  • 打赏
  • 举报
回复
要有很多匿名代理换着用
逍遥散人 2010-11-08
  • 打赏
  • 举报
回复
再次测试小结:

我把数据库数据查询这一步的屏蔽打开,但是在赋给url的时候仍然沿用的上面那段代码的..."北京联通"+i,这种方式也可以过32次的坎,分析问题出在关键字上?难道谷歌对关键字有要求?但从变化上来说,我的关键字也是随着i的变化而变化啊,只不过有规律而已(北京联通1、北京联通2、北京联通3....),快愁死我了....
逍遥散人 2010-11-08
  • 打赏
  • 举报
回复
见鬼了.......
我把从数据库中取数的循环语句屏蔽了,手写了一个for,居然正常了......

int i=0;
for (int j=0;j<=100;j++)
{
i++;
richTextBox1.Clear();
string url = "http://www.google.com.hk/search?hl=zh-CN&source=hp&biw=1280&bih=830&q=\"" + HttpUtility.HtmlEncode("北京联通" + i) + "\"";

XMLHTTP xmlhttp = new XMLHTTP();

xmlhttp.open("GET", url, false, null, null);
xmlhttp.send("");
Byte[] b = (Byte[])xmlhttp.responseBody;
string content = System.Text.ASCIIEncoding.UTF8.GetString(b, 0, b.Length);

txt_KeyWorld.Text = url;

richTextBox1.Text = content;
richTextBox1.Refresh();

label1.Text = i.ToString();
label1.Refresh();

Application.DoEvents();
Thread.Sleep(4000);
}

以上代码,除了循环语句外,其它的就没动过.....真想不明白,为什么从数据库里循环取数提交,和刚才那段代码手动赋给url值有什么区别吗?唯一区别就是数据库的循环是用的while。手动这个就是用for而已.....
逍遥散人 2010-11-07
  • 打赏
  • 举报
回复
有人能帮帮忙么?很急迫啊
逍遥散人 2010-11-07
  • 打赏
  • 举报
回复
应该和休眠无关吧,出错后我关掉程序,过一分钟左右再跑,又能跑32次......我怀疑还是和cookie有关,可是,我不知道怎么清除httpwebrequest的cookie啊。我清理了ie的cookie,不管用啊
  • 打赏
  • 举报
回复
那就休眠5分钟吧。
逍遥散人 2010-11-07
  • 打赏
  • 举报
回复
没人解决过此类问题么?
attlia 2010-11-07
  • 打赏
  • 举报
回复
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(mvarUrl);
request.Timeout = 20000;
//添加读写超时。
//request.ReadWriteTimeout = 20000;

WebResponse response;
try
{
response = request.GetResponse();
}
catch(Exception ee)
{
request.Abort();
request = null;
response = null;
//文件没有发现,直接返回。
if (ee.Message.Equals(m_400))
{
//说明不存在。
mvarUrl = null;
}
else
{
mvarUrl = null;
//失败,从新来过。
}
}
//若存在,则进行处理.
MemoryStream ms = new MemoryStream();
string strType = response.ContentType;

Stream ns = response.GetResponseStream();
//设置网络流超时时间.
ns.ReadTimeout = 6000;

byte[] nbytes = new byte[iLength];
int nReadSize = 1;
try
{
nReadSize = ns.Read(nbytes, 0, iLength);
while (nReadSize > 0)
{
ms.Write(nbytes, 0, nReadSize);
nReadSize = ns.Read(nbytes, 0, iLength);
}
byte[] bytes = ms.ToArray();
//说明成功。
DownComplete(mvarFileName, DownState.Complete, bytes);
ms.Close();
ms.Dispose();
ms = null;
ns.Close();
ns.Dispose();
ns = null;
request.Abort();
request = null;
response.Close();
response = null;
System.Threading.Thread.CurrentThread.Abort();
bytes = null;
}
catch// (Exception eeWeb)
{
//关闭。
ms.Close();
ns.Close();
//触发下载失败事件。
mvarUrl = null;
}


上述代码连接google网站没有问题。
phil999 2010-11-07
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 happyexp 的回复:]
不设置cookie container的话,一运行就报错......唉,郁闷死了,referer 和其他 http 头我也换了好几个了.....用proxy也试过,感觉没效果,还是那样......
[/Quote]

要用匿名代理,非常难找
asatoyt 2010-11-07
  • 打赏
  • 举报
回复
C# 怎么对chunked + gzip的 HTTP响应头解码?

哪位大哥能给我一个C#的实例呀。
iambic 2010-11-07
  • 打赏
  • 举报
回复
教训。你不停的请求肯定是不行的,Google防机器人是很在行也很严厉的,小心被永久封IP了。用代理列表,过不了多久那些代理也全被你搞挂了。找找Google有没有公开的API吧。另外你到底是在干啥,为什么要不停请求?
逍遥散人 2010-11-07
  • 打赏
  • 举报
回复
救救急啊,测试后发现,启动ie浏览器后,不停刷新(F5)页面,到第三十二次后就被谷歌封了,1-2分钟后点回退按钮重新查询又正常了,可是,我在代码里修改成判断次数到了30次后休眠2分钟,再抓,还是被封。我感觉是不是和cookie有关,可是,代码里的cookie每次都是重新new的一个啊,应该是不同的呀?
c_fans_2010 2010-11-07
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 phil999 的回复:]
这个只好用代理,但是,代理很难找,失效的也快。你的程序想顺畅的跑起来,还需要以下的东西:

1,代理列表,或者搜,或者买
2,代理的调度代码,一个代理不能连续使用多次,如果某次请求失败,那么换用新代理重试
3,代理的管理代码,如果发现一个代理失败率变的的很高,就把它从当前列表中移除
4,cookie, referer 和其他 http 头可能也要考虑
[/Quote]

帮顶...
加载更多回复(4)

111,129

社区成员

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

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

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