【小工具】實做 硬塞網 InsideJob 篩選器
年關將近,不少人興起了找工作的念頭。
我個人愛看硬塞網的一些資訊,硬塞網也提供了一個找工作的平台Inside Job Board。
但是,這年頭沒有個可以下條件的地方,感覺有點遜色了。
朋友也提出一樣的問題,所以,這篇文章誕生了。
雖然我昨天釋放出exe檔和上傳到GitHub中,但,猶豫了很久也研讀了一下關於法律問題的方面。
最終決定,完全撤離。依照Robots.txt,硬塞網並無不允許網路爬蟲,但,凡事說不定。
今日已經有寄信詢問硬塞網是否可以進行爬蟲行為了,若得到同意我還是會發佈。
在此之前,僅針對這樣的案例,來教學一下我怎麼達到我想要的目的。
需求:
- 沒有任何主機存放資料
- 抓取Inside Job的資料
- 可以下條件判斷資料是否符合
想法:
- 寫成Winform
- 每次使用者可以設定要抓幾頁的資訊(畢竟太多也只是舊資料)
- 有連結可以直接開瀏覽器到該職缺的網頁
準備技術:
- 網頁爬蟲,這次用Html Agility Pack來實做。
- Winform 技術,我非常少接觸Winform,大多還是用寫Webform的觀念下去寫。
- DataTable.Filter
主要分成四個區塊:
- 步驟一:資料建立:第一次使用者決定頁數後,讓爬蟲程式去撈資料回來,建立DataTable。
- 步驟二:工作清單:在爬蟲抓完資料後,會自己跳到這裡,列出抓到的清單。點選連結可以直接開啟該職缺網頁。
- 步驟三:資料篩選:可以做職缺、公司名稱、工作內容、工作地點、薪水範圍的篩選。
- 步驟四:詳細資料:在工作清單列表中,點選工作名稱可以列出詳細資訊。
做完的成品圖:
======================以下切回技術面======================
第一個動作了解你要爬的網頁,網頁動向等。
已InsideJob為例,下方式他們的網址,多翻幾頁你會發現,最後的數字根本就是PageNum的參數。
http://jobs.inside.com.tw/jobs/page/2
所以,我們可以透過迴圈去抓取一頁又一頁的資料。
第二個動作,他們的資訊排列整齊,列表式,這種網頁也蠻好分析的。
第三就只差你要會用Html Agility Pack啦!這邊推薦一個MSDN教學文:簡單好用快速的HTML Parser
以下列出,我開始抓取網頁資料的程式碼:
int JobCount = 0;
pgb1.Maximum = Convert.ToInt16(tbxCrawPage.Text.Trim());
DataTable oJobList = EmptyDataTable();
WebClient client = new WebClient();
string TargetUrl = oUrl + "/jobs/page/";
//這邊跑回圈看要抓幾頁
for (int i = 1; i <= Convert.ToInt16(tbxCrawPage.Text.Trim()); i++)
{
//整段包Try其實不太好,包起來主要原因是client.DownloadData時,若Server回應500錯誤,就掛了。
try
{
using (MemoryStream ms = new MemoryStream(client.DownloadData(TargetUrl + i.ToString())))
{
// 讀取 所有HTML HtmlAgilityPack.HtmlDocument
oHtml = new HtmlAgilityPack.HtmlDocument();
oHtml.Load(ms, Encoding.UTF8);
// 載取 目標Table Html HtmlAgilityPack.HtmlDocument
HtmlContext = new HtmlAgilityPack.HtmlDocument();
string oTargetHtml = oHtml.DocumentNode.SelectSingleNode("/html[1]/body[1]/div[2]/div[1]/div[1]/div[2]/div[1]/ul[1]").InnerHtml;
HtmlContext.LoadHtml(oTargetHtml);
//寫入每筆資料至Datatable
for (int j = 1; j <= HtmlContext.DocumentNode.SelectNodes("/li").Count; j++)
{
Entity.JobEntity oJob = new Entity.JobEntity();
//這樣寫可以直接抓到連結
oJob.Joblink = HtmlContext.DocumentNode.SelectSingleNode("/li[" + j + "]/a[1]").Attributes["href"].Value;
//這樣寫可以抓到裡面的文字
oJob.JobTitle = HtmlContext.DocumentNode.SelectSingleNode("/li[" + j + "]/a[1]/div[1]/h3[1]").InnerText;
DataRow oRow = oJobList.NewRow();
oRow["SerNo"] = JobCount + 1;
oRow["JobTitle"] = oJob.JobTitle;
oRow["Joblink"] = oUrl + oJob.Joblink;
oJobList.Rows.Add(oRow);
}
}
}
catch
{
continue;
}
}
public static DataTable EmptyDataTable()
{
DataTable workTable = new DataTable("InsideJobDT");
workTable.Columns.Add("SerNo", typeof(int));
workTable.Columns.Add("JobTitle", typeof(String));
//職缺名稱
workTable.Columns.Add("Joblink", typeof(String));
//Inside連結
return workTable;
}
其實抓網頁資料最麻煩的是剖析XPath,之前我用FireFox中的FireBug就可以直接指定元素,可以得到XPath。
但是,這次在抓的過程中,得到的XPath就是錯的(Div少一層),原因不明。
最後也是靠Html Agility Pack提供的軟體完成,軟體:HAP Explorer
程式碼中,我扣除了很多的欄位,畢竟這只是教學文。
解決上述,基本上工作清單的資料來源就有了。
我們看看資料設定這一段怎麼搞得吧!
DataView oDV = oJobList.DefaultView;
string Filter = "";
if (!string.IsNullOrEmpty(tbxJobTitle.Text.Trim()))
Filter += " JobTitle like '%" + tbxJobTitle.Text.Trim() + "%' | ";
if (!string.IsNullOrEmpty(tbxCompanyName.Text.Trim()))
Filter += " JobCompanyName like '%" + tbxCompanyName.Text.Trim() + "%' | ";
if (!string.IsNullOrEmpty(tbxJobInfo.Text.Trim()))
Filter += " JobInfo like '%" + tbxJobInfo.Text.Trim() + "%' | ";
if (!string.IsNullOrEmpty(tbxPayMin.Text.Trim()))
Filter += " JobPayMin >= " + tbxPayMin.Text.Trim() + " | ";
oDV.RowFilter = Filter.Trim().TrimEnd('|').Replace("|", "and");
lblJobCount.Text = "共有" + oDV.Count.ToString() + "職缺";
gvResult.AutoGenerateColumns = false;
gvResult.DataSource = oDV;
因為不知道會有幾個條件,所以用了一個小小技巧,透過TrimEnd把最後一個特殊符號去掉,再把特殊符號換成and。
取出詳細資料也是透過RowFilter來做,就不另外說明了。
最後,Winform 的DataGridView裡面,按下連結要開啟瀏覽器也是需要額外處裡。
類似webform 的 GridView 有RomCommand事件。
if (e.ColumnIndex == 8 && e.RowIndex >= 0)
{
string Link = Convert.ToString(gvResult.Rows[e.RowIndex].Cells[e.ColumnIndex].Value);
System.Diagnostics.Process.Start(Link);
}
以上這些事情,應該已經足以打造這樣一隻程式了。
希望有一天,可以發佈完整程式供給有需要的大家使用。
謝謝!
20151129更新:
把程式放上GitHub,有興趣的人可以自行使用,網站資料為該網站所有,請勿用無惡意途徑上。
純屬交流&學習用,若有任何責任本人不予負責。
目前該網站版頁面有異動過,所以,XPath已經變更,若有需求請自行修改程式。
https://github.com/kkman021/InsideJobCrawlerAP