多多色-多人伦交性欧美在线观看-多人伦精品一区二区三区视频-多色视频-免费黄色视屏网站-免费黄色在线

國內最全IT社區平臺 聯系我們 | 收藏本站
阿里云優惠2
您當前位置:首頁 > php開源 > php教程 > 被管理員和諧了的最高票答案“知乎數據抓取程序”(.net、c#數據挖掘)

被管理員和諧了的最高票答案“知乎數據抓取程序”(.net、c#數據挖掘)

來源:程序員人生   發布時間:2015-03-04 08:49:08 閱讀次數:4414次


問:能利用爬蟲技術做到哪些很酷很有趣很有用的事情?

準備學習python爬蟲。各位大神都會用爬蟲做哪些有趣的事情?

今天突然想玩玩爬蟲,就提了這個問題。隨著YouTube上的1個tutor寫了個簡單的程序,爬了1點豆瓣的數據。主要用到request和bs4(BeautifulSoup)模塊。雖然簡陋,畢竟是人生中的第1只爬蟲啊……以示記念,代碼寫在博客里了:我的第1只爬蟲:爬取豆瓣讀書


沒想到第1次答題竟然登上了知乎互聯網專欄的榜首了,也上了知乎首頁,惋惜被和諧了。




答:

監測她(他)的知乎,她關注、回答、贊了某個問題立馬電腦和手機都彈出提示是否是很酷!先上兩張圖:




我是個.NET程序猿,有1天女神告知我有1個很不錯的社區叫“知乎”,我常常1過來就看到她在看知乎,但每次我想看她都看了啥啊,她就遮住屏幕不讓我看。因而乎,在我心里埋下了1顆強烈的好奇心。知乎中搜了下她的名字,經過各種挑選知道了她的知乎空間。第1時間出現的想法是我要寫個監測程序,她關注的所有問題我都想知道。
連續奮戰5小時,至清晨3點程序終究寫出來了。主要HttpWebRequest加正則表達式來抓取數據,程序開機自動運行,數據庫設在1臺24小時開機的服務器上。多個監測客戶端同時運行,公司的,家里的,遠程服務器上的。每隔5分鐘自動循環讀取1次數據,如果檢測到關注了新的問題,立馬將它們發送至我的QQ郵箱和我的163郵箱,大家都知道QQ郵箱有提示功能,1發過來,立馬會彈出1個窗體告知你有新的郵件。手機qq客戶端也有,所以不管我是在上班的路上,還是在電腦旁,只要她有新動態我立馬就知道了。是否是很酷?
監測程序已運行3個多月了,搜集了他23百個關注的問題,我知道她1般都是吃中飯或晚餐前喜歡看1下知乎,晚上睡前會看會,她睡得早但偶爾清晨1點多還看知乎。她關注情感類的問題最多,而且那段時間我1直在追她,所以我能根據她關注的問題來推測她的1些想法,包括約會聊天時我可以聊1些她感興趣的話題。所以實用性還是比較強的。
假設某1天清晨1點,手機突然響了1下,發現她關注了某個問題。立馬給她發1條短信過去,你是否是還沒睡啊? 是啊,你怎樣知道我沒睡的? 憑感覺! 嘿嘿。 然后漸漸靠近她關注的那個話題去聊,這是否是會讓她感覺到你特別懂她。好奇你竟然知道她睡沒睡,好奇你和她聊的話那末符合她的心聲。

如此利器,有誰想要的嗎? 贊超過1百,程序和源代碼都放知乎上同享。

====21日9:37更新=====
沒想到第1次答題就上榜了,好不開心,來來來,別停哈。怒上榜首,我開源12306搶票源碼。我先赴約去開源我的知乎監測程序吧,1會把鏈接發過來。謝謝大家的贊!


===============


====21日11:50更新=====
《關于隱私》
先說明下,很多人都說我這樣做侵犯隱私?沒有吧,這些數據都是公然的啊,她也知道我關注了她呀,但蛋疼的知乎客戶端沒有這么細致的提示功能,我乃至在客戶端上找不到我都關注了哪些人。知乎手機app開發團隊弱爆了,這么強有力的需求竟然沒有滿足? 而且,知乎!你怎樣就沒有定閱功能呢?郵箱定閱! 我提出來啦哈,采用了給我大V可好?

《關于匿不匿名》
FK,男子漢大丈夫,匿啥名啊。女神知道了就知道了,又不是做甚么喪盡天良的事,敢作敢當!之所以寫這么1個程序,也其實不是完全的偷窺心理。對1個程序員來講,寫出1個新鮮的程序是能給程序員1種很大的樂趣的,這1般人難以理解,想當年在學校時,通宵寫俄羅斯方塊,白天上課不聽課在那研究1個方塊當按左鍵是甚么模樣甚么邏輯,右鍵又怎樣。這是非常成心思的事,編程實際上是1個藝術活,好的框架和優良的代碼讓人1看就感覺特別享受。 所以我寫這么個程序一樣也是滿足自己的1種樂趣。沒必要匿!

《關于女神追到沒?》
追到啦,哈哈!好爽啊,9月份去騎了趟川藏線,路遇佛像及經輪,我就祈禱我要娶她做老婆。且動身前找牛逼大神算了1卦(中國易學協會副會長),說我10月份很有姻緣緣分。因而,我在世界3大冰川之1的-來古冰川的河床上找了1下午的石頭,終究找到1顆天然紅色心形的愛情石,回來后我就拿著石頭跟她表白了,然后就成了!雖然她說我表白像檢討1樣,但也很感人!
惋惜,我們在1起沒多久就分手了。緣由1兩句話說不完,總之不管以后怎樣。都祝愿她,雖然在1起不長時間,但那是很美的回想。我會收藏!
===================


=====2015⑴⑵1 上午11:16分更新=======

程序開源地址:

下載源程序http://download.csdn.net/detail/wuyidexinsheng/8382253
程序博文地址:http://blog.csdn.net/wuyidexinsheng/article/details/42964707


步入正題,思路描寫:

下來源程序后,先自己去建數據庫改配置哈,否則程序運行不起來的。
<span style="font-size:10px;"><?xml version="1.0"?> <configuration> <appSettings> <!--數據有兩種存儲方式,1種存儲于本地程序目錄下的Ids.txt,但那只存了問題ID,完全的數據存于oracle數據庫中--> <add key="connStr" value="Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=127.0.0.1)(PORT=1521)))(CONNECT_DATA=(SERVER=DEDICATED)(SERVICE_NAME=DZZH)));User Id=xxxxx;Password=xxxx"/> <!-- 設置監測循環時間:秒 --> <add key="Interval" value="600"/> <!--設置自動發送信息機器人郵箱--> <add key="smtpAddress" value="smtp.163.com"/> <!--用戶名--> <add key="sendEmailFrom" value="xxxxxxxx@163.com"/> <!--密碼--> <add key="sendEmailFromPwd" value="xxxxxxxxx"/> <!--接收郵箱地址--> <add key="strMailAddressTo" value="xxxxxxxx@163.com,xxxxxxxx@qq.com"/> <!--郵件名稱抬頭--> <add key="EmailName" value="zhApp-家里電腦"/> <!--END--> <!--監測地址--> <add key="WatchingURL" value="http://www.zhihu.com/people/wu-xin-sheng⑺"/> </appSettings> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/> </startup> </configuration></span>

第1步:通過Cinser.Common.HttpHelper.GetString(“www.zhihu.com/people/wu-xin-sheng⑺”)讀取給定的1個網址的后臺代碼:

結果以下圖所示:


如我空間的源碼中就有這么1段:

<span class="name">伍新生</span>,<span class="bio" title="5顏6色的情感,我終生的尋求!">5顏6色的情感,我終生的尋求!</span> </div> </div> <div class="body clearfix"> <div class="zm-profile-header-avatar-container self"> <img alt="伍新生" src="http://pic4.zhimg.com/94cc60166_l.jpg" class="zm-profile-header-img zg-avatar-big zm-avatar-editor-preview"/> <span class="zm-entry-head-avatar-edit-button">修改頭像</span>

第2步:通過調用方法private List<Question> GetQuestions(string source)截取關鍵數據。

原理很簡單,所有知乎的問題都是以下的格式:<aclass="question_link"target="_blank"href="/question/27621722/answer/37636385">能利用爬蟲技術做到哪些很酷很有趣很有用的事情?</a>

接下來那就是字符串截取唄:調用Cinser.Common.StringPlus.SubString(source, “<a class="question_link”, "</a>")等順次截取問題的ID,名稱等數據。

private List<Question> GetQuestions(string source) { List<Question> questions = new List<Question>(); string startStr = "<a class="question_link""; if (source.IndexOf(startStr) != ⑴) { Question q = new Question(); string content = Cinser.Common.StringPlus.SubString(source, startStr, "</a>"); q.Id = Cinser.Common.StringPlus.SubString(content, "question/", """); q.Title = content.Substring(content.IndexOf(">") + 1); q.Time = DateTime.Now; questions.Add(q); source = source.Substring(source.IndexOf(startStr) + startStr.Length); questions.AddRange(GetQuestions(source)); } return questions; }

第3步:將取到的問題寫入數據庫,并寫入本地Ids.txt。

由于5分鐘讀取1次數據,肯定會讀取到部份已度過的數據咯。就是通過取到id然后看Ids.txt里面這個id是否是已存在了,如果存在了就表示已抓去過啦。 

為何問題都已寫到oracle數據庫了還要往本地Ids.txt寫1次呢,由于oracle數據庫是部署在遠程服務器上的啊。如果這臺服務器突然出故障死機了,怎樣辦?程序還得要運行啊,所以程序往兩個地方都寫1次數據。如果oracle數據庫不能訪問,則通過讀取和寫入本地ids來記錄問題。


數據抓取其實就這么簡單。


以下是部份源碼,也能夠直接去下載源程序:http://download.csdn.net/detail/wuyidexinsheng/8382253

以下是程序主窗體源碼:

public partial class Form1 : Form { DataProvider dal; string watchingURL = string.Empty; int LoopCount = 0; public Form1() { InitializeComponent(); dal = new DataProvider(); dal.AddLog("程序啟動"); base.WindowState = FormWindowState.Minimized; base.Show(); base.Hide(); base.WindowState = FormWindowState.Normal; base.ShowInTaskbar = false; base.TopMost = false; base.MaximizeBox = false; base.MinimizeBox = false; base.ControlBox = false; //設置循環監測時間 int interval = int.Parse(Cinser.Common.ConfigurationHelper.GetAppSettingsValue("Interval")); timer1.Interval = interval * 1000; watchingURL = Cinser.Common.ConfigurationHelper.GetAppSettingsValue("WatchingURL"); RunWhenStart(true, "zhApp.exe", """ + Application.StartupPath + "zhApp.exe" AutoRun"); Run(); dal.AddLog("程序初始化成功"); LoopCount += 1; } //設置程序開機自啟動 public void RunWhenStart(bool Started, string name, string path) { RegistryKey HKLM = Registry.CurrentUser; RegistryKey Run = HKLM.CreateSubKey(@"SOFTWAREMicrosoftWindowsCurrentVersionRun"); if (Started == true) { try { Run.SetValue(name, path); HKLM.Close(); } catch(Exception ex)//沒有權限會異常 { throw ex; } } else { try { Run.DeleteValue(name); HKLM.Close(); } catch (Exception ex)//沒有權限會異常 { throw ex; } } } /// <summary> /// 運行監測流程 /// </summary> private void Run() { List<Question> questions = GetQuestions(Cinser.Common.HttpHelper.GetString(watchingURL)); string ids = dal.GetExistIdsStr(); for (int i = 0; i < questions.Count; i++) { if (ids.IndexOf(questions[i].Id) != ⑴) { questions.Remove(questions[i]); i--; } else { if (ids == string.Empty) ids = questions[i].Id; else ids += "," + questions[i].Id; } } if (questions.Count > 0) { SendQuestions(questions); dal.WriteIdStrToTxt(ids); dal.Add(questions); dal.AddLog(string.Format("獲得了{0}條新數據。", questions.Count)); } } /// <summary> /// 從監測站點源數據中抓取問題 /// </summary> private List<Question> GetQuestions(string source) { List<Question> questions = new List<Question>(); string startStr = "<a class="question_link""; if (source.IndexOf(startStr) != ⑴) { Question q = new Question(); string content = Cinser.Common.StringPlus.SubString(source, startStr, "</a>"); q.Id = Cinser.Common.StringPlus.SubString(content, "question/", """); q.Title = content.Substring(content.IndexOf(">") + 1); q.Time = DateTime.Now; questions.Add(q); source = source.Substring(source.IndexOf(startStr) + startStr.Length); questions.AddRange(GetQuestions(source)); } return questions; } private bool SendQuestions(List<Question> questions) { bool bSuccess = true; List<string> strMailAddressTo = Cinser.Common.ConfigurationHelper.GetAppSettingsValue("strMailAddressTo").Split(',').ToList(); string smtpAddress = Cinser.Common.ConfigurationHelper.GetAppSettingsValue("smtpAddress"); string sendEmailFrom = Cinser.Common.ConfigurationHelper.GetAppSettingsValue("sendEmailFrom"); string sendEmailFromPwd = Cinser.Common.ConfigurationHelper.GetAppSettingsValue("sendEmailFromPwd"); string emailName = Cinser.Common.ConfigurationHelper.GetAppSettingsValue("EmailName"); //密碼解密,開源的話就去掉這步吧,這樣配置的時候直接配置明文密碼就行。 //sendEmailFromPwd = Cinser.Common.Security.DecryptDES(sendEmailFromPwd, "yuiophgf"); string msg = string.Empty; SendCompletedEventHandler s = new SendCompletedEventHandler(SendCompleted); string content = GetQustionsListStr(questions); content += " 信息來源于:" + watchingURL; Cinser.Common.SmtpEmailSend.SendEmail(strMailAddressTo, emailName + DateTime.Now.ToString(), content, smtpAddress, 0x19, sendEmailFrom, sendEmailFromPwd, "163測試郵箱", null, out msg, s); return bSuccess; } private void SendCompleted(object sender, AsyncCompletedEventArgs e) { } private string GetQustionsListStr(List<Question> questions) { string content = string.Empty; if (questions != null && questions.Count > 0) { content = string.Format("名稱:{0},url:{1}", questions[0].Title, questions[0].Url); for (int i = 1; i < questions.Count; i++) { content += string.Format(" 名稱:{0},url:{1}", questions[i].Title, questions[i].Url); } } return content; } private void timer1_Tick(object sender, EventArgs e) { int interval = int.Parse(Cinser.Common.ConfigurationHelper.GetAppSettingsValue("Interval")); timer1.Interval = interval * 1000; Run(); dal.AddLog(string.Format("程序循環次數:{0}", LoopCount++)); } }


知乎問題model:Question.cs

public class Question { string id, title, url, type, remark; DateTime time; public string Remark { get { return remark; } set { remark = value; } } public DateTime Time { get { return time; } set { time = value; } } public string Type { get { return type; } set { type = value; } } public string Url { get { if (string.IsNullOrEmpty(url)) { url = string.Format("http://www.zhihu.com/question/{0}", Id); } return url; } set { url = value; } } public string Title { get { return title; } set { title = value; } } public string Id { get { return id; } set { id = value; } } }

數據操作類DataProvider.cs

/// <summary> /// 知乎問題數據表操作Provider /// </summary> public class DataProvider { private string connStr = string.Empty; Cinser.DBUtility.DAL.OracleDALCommon dal; string txtPath = ""; string logPath = ""; string debugPath = string.Empty; public string DebugPath { get { if (debugPath == string.Empty) debugPath = System.AppDomain.CurrentDomain.BaseDirectory; if (debugPath.EndsWith("") == false) { debugPath += ""; } return debugPath; } set { debugPath = value; } } public string LogPath { get { if (logPath == string.Empty) { logPath = DebugPath + "Log.txt"; } return logPath; } } public DataProvider() { dal = new Cinser.DBUtility.DAL.OracleDALCommon(this.ConnStr); } public string TxtPath { get { if (txtPath == string.Empty) { txtPath = DebugPath + "Ids.txt"; } return txtPath; } } public string ConnStr { get { if (connStr == string.Empty) { connStr = Cinser.Common.ConfigurationHelper.GetAppSettingsValue("connStr"); } return connStr; } set { connStr = value; } } public bool CanConnectOracleServer { get { return dal.Open(); } } /// <summary> /// 將抓取到的問題寫入oracle數據庫中 /// </summary> /// <param name="questions"></param> /// <returns></returns> public bool Add(List<Question> questions) { bool bReturn = false; try { for (int i = 0; i < questions.Count; i++) { dal.Add("qustions", questions[i]); } bReturn = true; } catch { } return bReturn; } public DataTable GetQustions(string sqlWhere = "1=1") { try { DataTable dt = dal.GetDataList("qustions", sqlWhere); return dt; } catch { return null; } } public bool IsExist(string id) { try { string sqlWhere = "id='" + id + "'"; DataTable dt = dal.GetDataList("qustions", sqlWhere); return dt.Rows.Count > 0; } catch { return false; } } /// <summary> /// 獲得已抓取過的問題ID字符串 /// </summary> /// <returns></returns> public string GetExistIdsStr() { string ids = string.Empty; //如果能連上遠程的oracle服務器則從oracle數據庫中取ID字符串 if (CanConnectOracleServer) { DataTable dt = GetQustions(); if (dt != null && 主站蜘蛛池模板: 午夜影院免费看 | 日本不卡高清中文字幕免费 | 欧美最猛黑人xxxxx猛交 | 最近中文字幕高清中文字幕在线看 | 一区视频在线播放 | 国产中文久久精品 | 欧美一区亚洲二区 | 国产一区二区免费不卡在线播放 | 久久精品一区二区三区资源网 | 男女激情视频软件 | 精品国产日韩久久亚洲 | 国产精品欧美日韩 | 中文字幕在线观看免费视频 | 91视频一区二区三区 | 一级亚洲 | 久久久久18| 国产成人精品久久一区二区三区 | 性做久久久久久久 | 国产亚洲福利一区二区免费看 | 久久伊人网站 | 亚欧成人毛片一区二区三区四区 | 外国美女一级片 | 欧美xxxx极品流血 | 国产精品欧美韩国日本久久 | 日本中文字幕乱码免费 | 欧美一级欧美一级高清 | 亚洲欧美日韩在线观看播放 | 国产偷v国产偷v国产 | 视频一区 国产 | 欧美一级欧美三级 | 最近最新在线中文字幕 | 中文字幕日本一本二本三区 | 亚洲区小说区图片区qvod | 国产 日韩 一区 | 亚洲玖玖 | 国内精品伊人久久大香线焦 | 日本亚洲视频 | 欧美偷拍自拍视频 | xxxx欧美视频| 亚洲欧美日韩综合在线一区二区三区 | 国产一区二区不卡 |