C#制作多線程處理強(qiáng)化版網(wǎng)絡(luò)爬蟲
上次做了一個(gè)幫公司妹子做了爬蟲,不是很精致,這次公司項(xiàng)目里要用到,于是有做了一番修改,功能添加了網(wǎng)址圖片采集,下載,線程處理界面網(wǎng)址圖片下載等。
說說思路:首相獲取初始網(wǎng)址的所有內(nèi)容 在初始網(wǎng)址采集圖片 去初始網(wǎng)址采集鏈接 把采集到的鏈接放入隊(duì)列 繼續(xù)采集圖片,然后繼續(xù)采集鏈接,無限循環(huán)
還是上圖片大家看一下,

處理網(wǎng)頁內(nèi)容抓取跟網(wǎng)頁網(wǎng)址爬取都做了改進(jìn),下面還是大家來看看代碼,有不足之處,還請(qǐng)之處!
網(wǎng)頁內(nèi)容抓取HtmlCodeRequest,
網(wǎng)頁網(wǎng)址爬取GetHttpLinks,用正則去篩選html中的Links
圖片抓取GetHtmlImageUrlList,用正則去篩選html中的Img
都寫進(jìn)了一個(gè)封裝類里面 HttpHelper
/// <summary>
/// 取得HTML中所有圖片的 URL。
/// </summary>
/// <param name="sHtmlText">HTML代碼</param>
/// <returns>圖片的URL列表</returns>
public static string HtmlCodeRequest(string Url)
{
if (string.IsNullOrEmpty(Url))
{
return "";
}
try
{
//創(chuàng)建一個(gè)請(qǐng)求
HttpWebRequest httprequst = (HttpWebRequest)WebRequest.Create(Url);
//不建立持久性鏈接
httprequst.KeepAlive = true;
//設(shè)置請(qǐng)求的方法
httprequst.Method = "GET";
//設(shè)置標(biāo)頭值
httprequst.UserAgent = "User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705";
httprequst.Accept = "*/*";
httprequst.Headers.Add("Accept-Language", "zh-cn,en-us;q=0.5");
httprequst.ServicePoint.Expect100Continue = false;
httprequst.Timeout = 5000;
httprequst.AllowAutoRedirect = true;//是否允許302
ServicePointManager.DefaultConnectionLimit = 30;
//獲取響應(yīng)
HttpWebResponse webRes = (HttpWebResponse)httprequst.GetResponse();
//獲取響應(yīng)的文本流
string content = string.Empty;
using (System.IO.Stream stream = webRes.GetResponseStream())
{
using (System.IO.StreamReader reader = new StreamReader(stream, System.Text.Encoding.GetEncoding("utf-8")))
{
content = reader.ReadToEnd();
}
}
//取消請(qǐng)求
httprequst.Abort();
//返回?cái)?shù)據(jù)內(nèi)容
return content;
}
catch (Exception)
{
return "";
}
}
/// <summary>
/// 提取頁面鏈接
/// </summary>
/// <param name="html"></param>
/// <returns></returns>
public static List<string> GetHtmlImageUrlList(string url)
{
string html = HttpHelper.HtmlCodeRequest(url);
if (string.IsNullOrEmpty(html))
{
return new List<string>();
}
// 定義正則表達(dá)式用來匹配 img 標(biāo)簽
Regex regImg = new Regex(@"<img\b[^<>]*?\bsrc[\s\t\r\n]*=[\s\t\r\n]*[""']?[\s\t\r\n]*(?<imgUrl>[^\s\t\r\n""'<>]*)[^<>]*?/?[\s\t\r\n]*>", RegexOptions.IgnoreCase);
// 搜索匹配的字符串
MatchCollection matches = regImg.Matches(html);
List<string> sUrlList = new List<string>();
// 取得匹配項(xiàng)列表
foreach (Match match in matches)
sUrlList.Add(match.Groups["imgUrl"].Value);
return sUrlList;
}
/// <summary>
/// 提取頁面鏈接
/// </summary>
/// <param name="html"></param>
/// <returns></returns>
public static List<string> GetHttpLinks(string url)
{
//獲取網(wǎng)址內(nèi)容
string html = HttpHelper.HtmlCodeRequest(url);
if (string.IsNullOrEmpty(html))
{
return new List<string>();
}
//匹配http鏈接
const string pattern2 = @"http(s)?://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?";
Regex r2 = new Regex(pattern2, RegexOptions.IgnoreCase);
//獲得匹配結(jié)果
MatchCollection m2 = r2.Matches(html);
List<string> links = new List<string>();
foreach (Match url2 in m2)
{
if (StringHelper.CheckUrlIsLegal(url2.ToString()) || !StringHelper.IsPureUrl(url2.ToString()) || links.Contains(url2.ToString()))
continue;
links.Add(url2.ToString());
}
//匹配href里面的鏈接
const string pattern = @"(?i)<a\s[^>]*?href=(['""]?)(?!javascript|__doPostBack)(?<url>[^'""\s*#<>]+)[^>]*>"; ;
Regex r = new Regex(pattern, RegexOptions.IgnoreCase);
//獲得匹配結(jié)果
MatchCollection m = r.Matches(html);
foreach (Match url1 in m)
{
string href1 = url1.Groups["url"].Value;
if (!href1.Contains("http"))
{
href1 = Global.WebUrl + href1;
}
if (!StringHelper.IsPureUrl(href1) || links.Contains(href1)) continue;
links.Add(href1);
}
return links;
}
這邊下載圖片有個(gè)任務(wù)條數(shù)限制,限制是200條。如果超過的話線程等待5秒,這里下載圖片是異步調(diào)用的委托
public string DownLoadimg(string url)
{
if (!string.IsNullOrEmpty(url))
{
try
{
if (!url.Contains("http"))
{
url = Global.WebUrl + url;
}
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
request.Timeout = 2000;
request.UserAgent = "User-Agent:Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR 1.0.3705";
//是否允許302
request.AllowAutoRedirect = true;
WebResponse response = request.GetResponse();
Stream reader = response.GetResponseStream();
//文件名
string aFirstName = Guid.NewGuid().ToString();
//擴(kuò)展名
string aLastName = url.Substring(url.LastIndexOf(".") + 1, (url.Length - url.LastIndexOf(".") - 1));
FileStream writer = new FileStream(Global.FloderUrl + aFirstName + "." + aLastName, FileMode.OpenOrCreate, FileAccess.Write);
byte[] buff = new byte[512];
//實(shí)際讀取的字節(jié)數(shù)
int c = 0;
while ((c = reader.Read(buff, 0, buff.Length)) > 0)
{
writer.Write(buff, 0, c);
}
writer.Close();
writer.Dispose();
reader.Close();
reader.Dispose();
response.Close();
return (aFirstName + "." + aLastName);
}
catch (Exception)
{
return "錯(cuò)誤:地址" + url;
}
}
return "錯(cuò)誤:地址為空";
}
話不多說,更多的需要大家自己去改進(jìn)咯!歡迎讀者來與樓主進(jìn)行交流。
相關(guān)文章
C#中使用IrisSkin2.dll美化WinForm程序界面的方法
這篇文章主要介紹了c#中使用IrisSkin2.dll美化WinForm程序界面的實(shí)現(xiàn)方法,需要的朋友可以參考下2013-05-05
C#自定義RSA加密解密及RSA簽名和驗(yàn)證類實(shí)例
這篇文章主要介紹了C#自定義RSA加密解密及RSA簽名和驗(yàn)證類,實(shí)例分析了C#實(shí)現(xiàn)RSA加密解密及RSA簽名和驗(yàn)證的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
C#使用Socket實(shí)現(xiàn)心跳的方法示例
這篇文章主要介紹了C#使用Socket實(shí)現(xiàn)心跳的方法示例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02
C#獲取文件名和文件路徑的兩種實(shí)現(xiàn)方式
這篇文章主要介紹了C#獲取文件名和文件路徑的兩種實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07
基于C#實(shí)現(xiàn)Windows后臺(tái)窗口操作與圖像處理技術(shù)分析
在Windows編程中,操作后臺(tái)窗口是一項(xiàng)復(fù)雜而有用的技術(shù),它可以用來自動(dòng)化用戶界面測(cè)試、應(yīng)用程序機(jī)器人等場(chǎng)景,本文將深入探討如何在C#中綁定后臺(tái)窗口、獲取后臺(tái)窗口界面圖片,以及在圖片中尋找指定圖標(biāo)并獲取坐標(biāo),需要的朋友可以參考下2024-12-12
C#實(shí)現(xiàn)鬧鐘AlarmClock實(shí)例代碼
這篇文章主要介紹了C#實(shí)現(xiàn)鬧鐘AlarmClock實(shí)例代碼,很實(shí)用的功能,需要的朋友可以參考下2014-08-08

