网页爬虫抓取百度图片(怎么老是静不下心来心来搞定一方面的技术,再学点其他的东西)
优采云 发布时间: 2022-03-12 03:11网页爬虫抓取百度图片(怎么老是静不下心来心来搞定一方面的技术,再学点其他的东西)
我对xmfdsh真的很感兴趣,为什么不能静下心来搞定一个方面的技术,然后再学习其他的东西,一步一步来,好吧,我又要去学习网络爬虫了,这是一个简单的版本,参考网上很多资料,用C#写的,专门抓图,可以抓一些需要cookies的网站,所以功能还是挺全的,xmfdsh才研究了三天,所以有仍有很大的改进空间。我会慢慢改进的。我将在本文末尾附上整个项目。献给喜欢学习C#的朋友。让我慢慢说:
#region 访问数据 + Request(int index)
///
/// 访问数据
///
private void Request(int index)
{
try
{
int depth;
string url = "";
//lock锁住Dictionary,因为Dictionary多线程会出错
lock (_locker)
{
//查看是否还存在未下载的链接
if (UnDownLoad.Count 0)
{
MemoryStream ms = new System.IO.MemoryStream(rs.Data, 0, read);
BinaryReader reader = new BinaryReader(ms);
byte[] buffer = new byte[32 * 1024];
while ((read = reader.Read(buffer, 0, buffer.Length)) > 0)
{
rs.memoryStream.Write(buffer, 0, read);
}
//递归 再次请求数据
var result = responseStream.BeginRead(rs.Data, 0, rs.BufferSize, new AsyncCallback(ReceivedData), rs);
return;
}
}
else
{
read = responseStream.EndRead(ar);
if (read > 0)
{
//创建内存流
MemoryStream ms = new MemoryStream(rs.Data, 0, read);
StreamReader reader = new StreamReader(ms, Encoding.GetEncoding("gb2312"));
string str = reader.ReadToEnd();
//添加到末尾
rs.Html.Append(str);
//递归 再次请求数据
var result = responseStream.BeginRead(rs.Data, 0, rs.BufferSize, new AsyncCallback(ReceivedData), rs);
return;
}
}
if (url.Contains(".jpg") || url.Contains(".png"))
{
//images = rs.Images;
SaveContents(rs.memoryStream.GetBuffer(), url);
}
else
{
html = rs.Html.ToString();
//保存
SaveContents(html, url);
//获取页面的链接
}
}
catch (Exception ex)
{
_reqsBusy[rs.Index] = false;
DispatchWork();
}
List links = GetLinks(html,url);
//得到过滤后的链接,并保存到未下载集合
AddUrls(links, depth + 1);
_reqsBusy[index] = false;
DispatchWork();
}
#endregion
这就是数据的*敏*感*词*孩的照片),如果不是图片,我们认为是正常的html页面,然后阅读html代码,如果有链接http或 href,它将被添加到下载链接。当然,对于我们阅读的链接,我们已经限制了一些js或者一些css(不要阅读这样的东西)。
private void SaveContents(byte[] images, string url)
{
if (images.Count() < 1024*30)
return;
if (url.Contains(".jpg"))
{
File.WriteAllBytes(@"d:\网络爬虫图片\" + _index++ + ".jpg", images);
Console.WriteLine("图片保存成功" + url);
}
else
{
File.WriteAllBytes(@"d:\网络爬虫图片\" + _index++ + ".png", images);
Console.WriteLine("图片保存成功" + url);
}
}
#region 提取页面链接 + List GetLinks(string html)
///
/// 提取页面链接
///
///
///
private List GetLinks(string html,string url)
{
//匹配http链接
const string pattern2 = @"http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?";
Regex r2 = new Regex(pattern2, RegexOptions.IgnoreCase);
//获得匹配结果
MatchCollection m2 = r2.Matches(html);
List links = new List();
for (int i = 0; i < m2.Count; i++)
{
//这个原因是w3school的网址,但里面的东西明显不是我们想要的
if (m2[i].ToString().Contains("www.w3.org"))
continue;
links.Add(m2[i].ToString());
}
//匹配href里面的链接,并加到主网址上(学网站的你懂的)
const string pattern = @"href=([""'])?(?[^'""]+)\1[^>]*";
Regex r = new Regex(pattern, RegexOptions.IgnoreCase);
//获得匹配结果
MatchCollection m = r.Matches(html);
// List links = new List();
for (int i = 0; i < m.Count; i++)
{
string href1 = m[i].ToString().Replace("href=", "");
href1 = href1.Replace("\"", "");
//找到符合的,添加到主网址(一开始输入的网址)里面去
string href = RootUrl + href1;
if (m[i].ToString().Contains("www.w3.org"))
continue;
links.Add(href);
}
return links;
}
#endregion
提取页面链接的方法,当阅读发现这是html代码时,继续解释里面的代码,找到里面的url链接,这正是拥有网络爬虫功能的方法(不然会很无聊只提取这个页面),这里当然应该提取http链接,href中的字是因为。. . . (学网站你懂的,很难解释)几乎所有的图片都放在里面,文章,所以上面有href之类的代码要处理。
#region 添加url到 UnDownLoad 集合 + AddUrls(List urls, int depth)
///
/// 添加url到 UnDownLoad 集合
///
///
///
private void AddUrls(List urls, int depth)
{
lock (_locker)
{
if (depth >= MAXDEPTH)
{
//深度过大
return;
}
foreach (string url in urls)
{
string cleanUrl = url.Trim();
int end = cleanUrl.IndexOf(' ');
if (end > 0)
{
cleanUrl = cleanUrl.Substring(0, end);
}
if (UrlAvailable(cleanUrl))
{
UnDownLoad.Add(cleanUrl, depth);
}
}
}
}
#endregion
#region 开始捕获 + DispatchWork()
///
/// 开始捕获
///
private void DispatchWork()
{
for (int i = 0; i < _reqCount; i++)
{
if (!_reqsBusy[i])
{
Request(i);
Thread.Sleep(1000);
}
}
}
#endregion
此功能是为了使这些错误起作用。_reqCount 的值在开头设置。事实上,视觉上的理解就是你发布的 bug 的数量。在这个程序中,我默认放了20个,可以随时修改。对于一些需要cookies的网站,就是通过访问开头输入的URL,当然也可以使用HttpWebRequest辅助类,cookies = request.CookieContainer; //保存cookie,以后访问后续URL时添加就行 request.CookieContainer = cookies; //饼干尝试。对于 网站 只能通过应用 cookie 访问,不需要根网页,就像不需要百度图片的 URL,但如果访问里面的图片很突然,cookie会附上,所以这个问题也解决了。xmfdsh 发现这个程序中还有一些网站不能抓图。当捕捉到一定数量的照片时它会停止。具体原因不明,以后慢慢完善。
附上源码:%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB.rar