玩轉C#之【爬蟲】

閱讀時間約 18 分鐘

介紹

基礎概念

爬蟲其實就是一個自動提取網頁的程式
程式基本運作:Url開始-->分析獲取數據&找到Url-->遞迴下去-->結束
分析獲取數據運作:下載html--解析獲取數據--數據保存

爬蟲可以做哪些事情?

數據為王:抓小說數據,做個內容站;
電影/動漫下載站
抓圖片
政府的公開招標數據,每天匯集這些數據

爬蟲的攻防

爬蟲的正義性問題:不違法、不問自取謂之偷
robots協議:君子的協定(360流氓),道德防線
每個網站會堤供robots.txt,來說明自己的哪些路徑允許爬資料
📷
防=>請求檢測header
攻=>爬蟲去都模擬一下
📷
防=>用戶登入
攻=>請求的時候帶上cookie
防:因為爬蟲的訪問頻率會很高,因此可以將訪問頻率高的IP加入黑名單,或者返回驗證碼
攻:可以透過以下方式產生多個ip(ADSL撥號/168偽裝IP/代理IP)
攻:破解驗證碼,有開源的圖片識別程式(OCR/打碼平台)
防:數據透過JS動態加載;將資料轉成圖片;透過JS收集用戶操作訊息,然後回傳伺服器;用戶控件(可以收集更多信息)
以上都是可以搞定的,道高一尺魔高一丈
手機板的請求抓取:裝模擬器=>電腦抓包Fiddler

下載html(HttpWebRequest)

string html = string.Empty;

HttpWebRequest request = HttpWebRequest.Create(url) as HttpWebRequest;//模擬請求
request.Timeout = 30 * 1000;//設置30s超時
request.UserAgent = "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.106 Safari/537.36";//pc瀏覽器
//request.UserAgent = "Ruanmou Crawler";
//request.UserAgent = "Mozilla / 5.0(iPhone; CPU iPhone OS 7_1_2 like Mac OS X) App leWebKit/ 537.51.2(KHTML, like Gecko) Version / 7.0 Mobile / 11D257 Safari / 9537.53";//手機板瀏覽器
request.ContentType = "text/html; charset=utf-8";// "text/html;charset=gbk";//
request.Host = "www.jd.com";

request.Headers.Add("Cookie", @"newUserFlag=1; guid=YFT7C9E6TMFU93FKFVEN7TEA5HTCF5DQ26HZ; gray=959782; cid=av9kKvNkAPJ10JGqM_rB_vDhKxKM62PfyjkB4kdFgFY5y5VO; abtest=31; _ga=GA1.2.334889819.1425524072; grouponAreaId=37; provinceId=20; search_showFreeShipping=1; rURL=http%3A%2F%2Fsearch.yhd.com%2Fc0-0%2Fkiphone%2F20%2F%3Ftp%3D1.1.12.0.73.Ko3mjRR-11-FH7eo; aut=5GTM45VFJZ3RCTU21MHT4YCG1QTYXERWBBUFS4; ac=57265177%40qq.com; msessionid=H5ACCUBNPHMJY3HCK4DRF5VD5VA9MYQW; gc=84358431%2C102362736%2C20001585%2C73387122; tma=40580330.95741028.1425524063040.1430288358914.1430790348439.9; tmd=23.40580330.95741028.1425524063040.; search_browse_history=998435%2C1092925%2C32116683%2C1013204%2C6486125%2C38022757%2C36224528%2C24281304%2C22691497%2C26029325; detail_yhdareas=""; cart_cookie_uuid=b64b04b6-fca7-423b-b2d1-ff091d17e5e5; gla=20.237_0_0; JSESSIONID=14F1F4D714C4EE1DD9E11D11DDCD8EBA; wide_screen=1; linkPosition=search");

//request.Headers.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8");
//request.Headers.Add("Accept-Encoding", "gzip, deflate, sdch");
//request.Headers.Add("Referer", "http://list.yhd.com/c0-0/b/a-s1-v0-p1-price-d0-f0-m1-rt0-pid-mid0-kiphone/");
request.Method = "GET";
//Encoding enc = Encoding.GetEncoding("GB2312"); // 如果是亂碼就改成 utf-8 / GB2312

#region Post
//int sort = 2;//人數
//string dataString = string.Format("k={0}&n=24&st={1}&iso=0&src=1&v=4093&p={2}&isRecommend=false&city_id=0&from=1&ldw=1361580739", keyword, sort, 1);
//Encoding encoding = Encoding.UTF8;//根據網站編碼自訂義
//byte[] postData = encoding.GetBytes(dataString);
//request.ContentLength = postData.Length;
//Stream requestStream = request.GetRequestStream();
//requestStream.Write(postData, 0, postData.Length);
#endregion

Encoding enc = Encoding.UTF8;//.GetEncoding("GB2312");
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)//發起請求
{
if (response.StatusCode != HttpStatusCode.OK)
{
logger.Warn(string.Format("抓取{0}地址返回失敗,response.StatusCode為{1}", url, response.StatusCode));
}
else
{
try
{
StreamReader sr = new StreamReader(response.GetResponseStream(), enc);
html = sr.ReadToEnd();//讀取數據
sr.Close();
}
catch (Exception ex)
{
logger.Error(string.Format($"DownloadHtml抓取{url}失敗"), ex);
html = null;
}
}
}
return html

日誌紀錄(Log4Net)

log4net.cfg設定檔
<?xml version="1.0" encoding="utf-8"?>
<log4net>
<!-- Define some output appenders -->
<appender name="rollingAppender" type="log4net.Appender.RollingFileAppender">
<file value="log\log.txt" />

<!--追加日誌內容-->
<appendToFile value="true" />

<!--防止多線程時不能寫Log,官方說線程非安全-->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />

<!--可以為:Once|Size|Date|Composite-->
<!--Composite為=為Size和Date的組合-->
<rollingStyle value="Composite" />

<!--當備份文件時,為文件名加的後綴-->
<datePattern value="yyyyMMdd.TXT" />

<!--日誌最大個數,都是最新的-->
<!--rollingStyle節點為Size時,只能有value個日誌-->
<!--rollingStyle節點為Composite時,每天有value個日誌-->
<maxSizeRollBackups value="20" />

<!--可用的單位:KB|MB|GB-->
<maximumFileSize value="3MB" />

<!--設置為true,當前最新日誌文件名永遠為file節中的名字-->
<staticLogFileName value="true" />

<!--輸出級別在INFO和ERROR之間的日誌-->
<filter type="log4net.Filter.LevelRangeFilter">
<param name="LevelMin" value="INFO" />
<param name="LevelMax" value="FATAL" />
</filter>

<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger - %message%newline"/>
</layout>
</appender>

<!-- levels: OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL -->
<root>
<priority value="ALL"/>
<level value="ALL"/>
<appender-ref ref="rollingAppender" />
</root>
</log4net>
Log Level的等級
OFF > FATAL > ERROR > WARN > INFO > DEBUG > ALL
初始化
static Logger()
{
XmlConfigurator.Configure(new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "CfgFiles\\log4net.cfg.xml")));
ILog Log = LogManager.GetLogger(typeof(Logger));
Log.Info("系統初始化Logger模塊");
}

private ILog loger = null;
public Logger(Type type)
{
loger = LogManager.GetLogger(type);
}
紀錄log的方式
使用log選擇要紀錄的等級
loger.Error(msg, ex);
loger.Warn(msg);
loger.Info(msg);
loger.Debug(msg);

解析HTML資料(HtmlAgiliytyPack)

通常在解析HttpWebRequest下載回來的HTML資料有兩種方式:
  1. 透過正則表達式搭配Substring/indexof/replace
  2. HtmlAgiliytyPack;基於Xpath解析

Xpath

什麼是XPath
XPath (XML Path Language) 是一種用來尋找XML文件中某個節點(node)位置的查詢語言。
XPath使用類似路徑的語法來尋找節點。
XPath一共有七種節點:element, attribute, text, namespace, processing-instruction, comment, document
XML文件是由許多節點組成的樹狀結構,最上層的結點稱作root element
  1. 假設要找這段文字的Xpath,先找到它的HTML位置
    📷
  2. 再對它的位置點右鍵=>Copy => CopyXPath
    📷
  3. 再透過XPath Helper 套件,可以驗證剛剛複製的XPath的路徑,是否正確
    📷

HtmlAgiliytyPack用法

  1. 新增HtmlDocument物件
  2. 使用LoadHtml存進HtmlDocument物件
  3. 使用SelectNodes找尋Xpath節點內容
public void Crawl()
{
//下載HTML
string html = HttpHelper.DownloadHtml("https://www.jd.com/allSort.aspx");
if (string.IsNullOrEmpty(html))
{
//需要重試。記錄下來
}
HtmlDocument document = new HtmlDocument();
document.LoadHtml(html);
{
//Xpath路徑
string secondPath = "//dl/dt/a";
HtmlNodeCollection nodeList = document.DocumentNode.SelectNodes(secondPath);//找多個節點
if (nodeList != null)
{
foreach (HtmlNode node in nodeList)
{
string url = node.Attributes["href"].Value;
string name = node.InnerText;
}
}
}
}

參考資料

本篇已同步發表至個人部落格
https://moushih.com/2022ithome26/
鐵人賽文章
即將進入廣告,捲動後可繼續閱讀
為什麼會看到廣告
8會員
39Content count
我是這個部落格的作者,喜歡分享有關投資 💰、軟體開發 💻、占卜 🔮 和虛擬貨幣 🚀 的知識和經驗。
留言0
查看全部
發表第一個留言支持創作者!
一代軍師 的其他內容
介紹 通常我們程式寫完之後,要確保程式沒問題我們就會進行測試 在這裡我們將測試分兩大類: 單元測試(Unit Test,UT):對程式碼的最小單位所進行的測試 整合測試(Integration Test):系統/模組之間的測試,通常會接觸到真實系統 在這裡只會簡單介紹一下單元測試的概念 這裡在將單元
介紹 原始碼(source code)→編譯器→中繼語言(MSIL)→CLR→電腦看得懂的語言(Native code) 所以我們可以知道,CLR( Common Language Runtime ):是 .NET Framework 的虛擬機器元件 (virtual machine compone
小心設計模式別亂用 📷 介紹 設計模式就是過去的人,根據常見的軟體設計的問題,提出的解決方案。 設計模式總共有23種,根據情境分成三大類型,建立型、結構型、行為型。 建立型模式(Creational Patterns) 簡單工廠(Simple Factory) 工廠方法(Factory) 抽象工廠
介紹 何謂原則(Principle) A principle is a concept or value that is a guide for behavior or evaluation 所謂【原則】(Principle)就是一種【概念】或【價值】,用來導引你產生適切的行為與價值評量方法 白話文
介紹 非同步程式設計模式(Asynchronous Programming Patterns) APM 非同步程式設計模型 EAP 事件架構非同步模式 TAP 以工作為基礎的非同步模式 先在主要以TAP APM (Asynchronous Programming Model) 非同步程式設計模型.N
介紹 委派的非同步方法 可以透過BeginInvoke執行委派的非同步方法 Action<T>.BeginInvoke(<T> obj,AsyncCallback callback,Object @object) 第一個內容的 obj,只的是要傳入acction委派的參數 第二個AsyncCallb
介紹 通常我們程式寫完之後,要確保程式沒問題我們就會進行測試 在這裡我們將測試分兩大類: 單元測試(Unit Test,UT):對程式碼的最小單位所進行的測試 整合測試(Integration Test):系統/模組之間的測試,通常會接觸到真實系統 在這裡只會簡單介紹一下單元測試的概念 這裡在將單元
介紹 原始碼(source code)→編譯器→中繼語言(MSIL)→CLR→電腦看得懂的語言(Native code) 所以我們可以知道,CLR( Common Language Runtime ):是 .NET Framework 的虛擬機器元件 (virtual machine compone
小心設計模式別亂用 📷 介紹 設計模式就是過去的人,根據常見的軟體設計的問題,提出的解決方案。 設計模式總共有23種,根據情境分成三大類型,建立型、結構型、行為型。 建立型模式(Creational Patterns) 簡單工廠(Simple Factory) 工廠方法(Factory) 抽象工廠
介紹 何謂原則(Principle) A principle is a concept or value that is a guide for behavior or evaluation 所謂【原則】(Principle)就是一種【概念】或【價值】,用來導引你產生適切的行為與價值評量方法 白話文
介紹 非同步程式設計模式(Asynchronous Programming Patterns) APM 非同步程式設計模型 EAP 事件架構非同步模式 TAP 以工作為基礎的非同步模式 先在主要以TAP APM (Asynchronous Programming Model) 非同步程式設計模型.N
介紹 委派的非同步方法 可以透過BeginInvoke執行委派的非同步方法 Action<T>.BeginInvoke(<T> obj,AsyncCallback callback,Object @object) 第一個內容的 obj,只的是要傳入acction委派的參數 第二個AsyncCallb
你可能也想看
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
進入物件導向設計的實戰階段,我們通過建立人力資源管理功能來實踐理論知識。透過這些實作練習,能夠深化對物件導向概念的理解,並學會如何在實際開發中應用這些概念。
Thumbnail
在物件導向程式設計的進階階段,學生將學習繼承、介面、抽象類別等核心概念。繼承允許類別共享屬性和方法,介面確保實現類別提供特定的方法實現,而抽象類別定義了基本結構供子類別擴展。這些知識點有助於提升程式碼的重用性、擴展性和維護性。
Thumbnail
暢銷懸疑小說的《法庭遊戲》改編為電影版,日前也在台灣上映,燒腦的情節加上法庭的諜對諜攻防;再加上永瀨廉、杉咲花、北村匠海三位高人氣演員加持。
Thumbnail
自2020年問世以來,日本潮流品牌Water The Plant便以其獨特的設計理念和色彩豐富的產品系列,在全球潮流文化中掀起了一股正能量的旋風。
Thumbnail
戴姆勒克萊斯勒出產的後輪驅動雙門跑車 Chrysler Crossfire(火線),使用 33% 賓士 SLK 跑車零件,在 2003 年推出,於 2007 年因為公司重組後停產。雖然,1:1 的新車買不起,那買台 1:18 的模型車來玩玩總是可以的。😜
Thumbnail
透過美圖秀秀APP「AI 繪畫藝術」測試版,你會發現龍虎塔的塔,你會發現龍虎塔的塔型,變得更古色古香,有些還幻化成了日本建築風格,塔前的石橋被東方風格的街頭古燈所取代,潭前的荷花池全轉換成荷花池全轉換成了日式的庭園與石階,與西式的建築與路燈,上面還被白雪覆蓋著,連塔邊的樹種,天際的背景也有了轉換,東
Thumbnail
每年各種APP都會推出各種免費的年節電子賀卡,有的免費有的要付費,耶誕節、台灣元旦新年、農曆過年與西洋情人節陸續將至,如果你有寄發電子賀卡的習慣,今年不妨試試以下推薦的新玩意--- 免費的「美圖秀秀APP 「AI 繪畫藝術」多種畫風一鍵生成」!
Thumbnail
在餐桌上,時不時喜歡做些新鮮的嘗試,不管是食材的搭配或是烹調的方法,又或是餐桌(就是道具很多啦)的形式,菜色的嘗試往往都來自於看到臉友PO的美食照,或者是自己在外面用餐時看到的擺盤與菜餚,本以為這些嘗試的最大樂趣是複製成功,但後來發現真正有趣的是過程中的摸索。
Thumbnail
C_29 / 'Optimist' 的整體空間是由雅典知名的 314 architecture studio 所打造,創立者 Pavlo Hatjiaggelide 的背景是一名專業的土木工程師,擅長架構設計和室內設計,其設計作品就像是高純度的藝術品。
Thumbnail
相比起Celsius每週派息一次,NEXO的好處就是它會每天派息一次,只要在每天07:00-08:00 CET時區前存入資金便可以開始計算利息,如果過了這個時段才存入資金的話,便可能要等24小時以上才能獲得利息了XD。 b. 填寫你的 Email 和密碼 【個人網站】 【加密貨幣】 【被動收入】
Thumbnail
1.加權指數與櫃買指數 週五的加權指數在非農就業數據開出來後,雖稍微低於預期,但指數仍向上噴出,在美股開盤後於21500形成一個爆量假突破後急轉直下,就一路收至最低。 台股方面走勢需觀察週一在斷頭潮出現後,週二或週三開始有無買單進場支撐,在沒有明確的反轉訊號形成前,小夥伴盡量不要貿然抄底,或是追空
Thumbnail
重點摘要: 1.9 月降息 2 碼、進一步暗示年內還有 50 bp 降息 2.SEP 上修失業率預期,但快速的降息速率將有助失業率觸頂 3.未來幾個月經濟數據將繼續轉弱,經濟復甦的時點或是 1Q25 季底附近
Thumbnail
近期的「貼文發佈流程 & 版型大更新」功能大家使用了嗎? 新版式整體視覺上「更加凸顯圖片」,為了搭配這次的更新,我們推出首次貼文策展 ❤️ 使用貼文功能並完成這次的指定任務,還有機會獲得富士即可拍,讓你的美好回憶都可以用即可拍珍藏!
Thumbnail
進入物件導向設計的實戰階段,我們通過建立人力資源管理功能來實踐理論知識。透過這些實作練習,能夠深化對物件導向概念的理解,並學會如何在實際開發中應用這些概念。
Thumbnail
在物件導向程式設計的進階階段,學生將學習繼承、介面、抽象類別等核心概念。繼承允許類別共享屬性和方法,介面確保實現類別提供特定的方法實現,而抽象類別定義了基本結構供子類別擴展。這些知識點有助於提升程式碼的重用性、擴展性和維護性。
Thumbnail
暢銷懸疑小說的《法庭遊戲》改編為電影版,日前也在台灣上映,燒腦的情節加上法庭的諜對諜攻防;再加上永瀨廉、杉咲花、北村匠海三位高人氣演員加持。
Thumbnail
自2020年問世以來,日本潮流品牌Water The Plant便以其獨特的設計理念和色彩豐富的產品系列,在全球潮流文化中掀起了一股正能量的旋風。
Thumbnail
戴姆勒克萊斯勒出產的後輪驅動雙門跑車 Chrysler Crossfire(火線),使用 33% 賓士 SLK 跑車零件,在 2003 年推出,於 2007 年因為公司重組後停產。雖然,1:1 的新車買不起,那買台 1:18 的模型車來玩玩總是可以的。😜
Thumbnail
透過美圖秀秀APP「AI 繪畫藝術」測試版,你會發現龍虎塔的塔,你會發現龍虎塔的塔型,變得更古色古香,有些還幻化成了日本建築風格,塔前的石橋被東方風格的街頭古燈所取代,潭前的荷花池全轉換成荷花池全轉換成了日式的庭園與石階,與西式的建築與路燈,上面還被白雪覆蓋著,連塔邊的樹種,天際的背景也有了轉換,東
Thumbnail
每年各種APP都會推出各種免費的年節電子賀卡,有的免費有的要付費,耶誕節、台灣元旦新年、農曆過年與西洋情人節陸續將至,如果你有寄發電子賀卡的習慣,今年不妨試試以下推薦的新玩意--- 免費的「美圖秀秀APP 「AI 繪畫藝術」多種畫風一鍵生成」!
Thumbnail
在餐桌上,時不時喜歡做些新鮮的嘗試,不管是食材的搭配或是烹調的方法,又或是餐桌(就是道具很多啦)的形式,菜色的嘗試往往都來自於看到臉友PO的美食照,或者是自己在外面用餐時看到的擺盤與菜餚,本以為這些嘗試的最大樂趣是複製成功,但後來發現真正有趣的是過程中的摸索。
Thumbnail
C_29 / 'Optimist' 的整體空間是由雅典知名的 314 architecture studio 所打造,創立者 Pavlo Hatjiaggelide 的背景是一名專業的土木工程師,擅長架構設計和室內設計,其設計作品就像是高純度的藝術品。
Thumbnail
相比起Celsius每週派息一次,NEXO的好處就是它會每天派息一次,只要在每天07:00-08:00 CET時區前存入資金便可以開始計算利息,如果過了這個時段才存入資金的話,便可能要等24小時以上才能獲得利息了XD。 b. 填寫你的 Email 和密碼 【個人網站】 【加密貨幣】 【被動收入】