新聞?wù)救洪_發(fā)日志(一)—— 新聞抓取

1. 了解需求

公司負(fù)責(zé)運(yùn)營(yíng)的同事找到我蘑辑,說需要搭建一個(gè)新聞?wù)救海糜谝肓髁孔寡纭C總€(gè)站的新聞數(shù)據(jù)都去別的新聞?wù)咀ト⊙蠡辏刻焱砩?0點(diǎn)更新數(shù)據(jù),每個(gè)站還需要單獨(dú)配置SEO(首頁(yè)喜鼓、頻道頁(yè)副砍、詳情頁(yè))、友情鏈接內(nèi)容豁翎。

拆分需求

  • 新聞抓取心剥,每個(gè)新聞?wù)镜淖ト?shù)據(jù)源都不一致蝉揍,所以抓取我們需要靈活配置又沾。
  • 每天定時(shí),所以我們需要一個(gè)Windows 服務(wù),定時(shí)完成抓取任務(wù)不瓶。
  • 新聞?wù)救?/strong>蚊丐,意味著會(huì)有很多站昭娩,如果每個(gè)站單獨(dú)一個(gè)數(shù)據(jù)庫(kù)呛梆,那么后期程序維護(hù)工作將會(huì)很龐大,所以我們需要做到一個(gè)庫(kù)對(duì)應(yīng)n個(gè)站

2. 功能實(shí)現(xiàn)

拆分需求后滞磺,接下來(lái)我們要挨個(gè)實(shí)現(xiàn)每個(gè)需求對(duì)應(yīng)的功能保礼。

新聞抓取

看到抓取時(shí)目派,首先想到的是HtmlAgilityPack,Github鏈接是https://github.com/zzzprojects/html-agility-pack谅摄,HtmlAgilityPack可以加載html,并且提供了函數(shù)SelectNodes闽寡,可以非常方便我們定位到需要抓取的DOM節(jié)點(diǎn)。下面看看這個(gè)函數(shù)的示例(http://html-agility-pack.net/select-nodes):

var htmlDoc = new HtmlDocument();
htmlDoc.LoadHtml(html);

string name = htmlDoc.DocumentNode
    .SelectNodes("http://td/input")
    .First()
    .Attributes["value"].Value;'

這里需要重點(diǎn)關(guān)注的是SelectNodes的參數(shù)//td/input,這個(gè)參數(shù)名叫XPath,那么我們?cè)趺慈〉揭粋€(gè)網(wǎng)站某個(gè)節(jié)點(diǎn)的XPath呢,可以通過Chrome瀏覽器直接獲取。首先打開我們的目標(biāo)網(wǎng)站:http://www.southcn.com/pc2016/yw/node_346416.htm结洼,我們要抓取的是列表部分,如下圖:

需要抓取的數(shù)據(jù)

確定好目標(biāo)后叉跛,我們可以通過Chrome直接復(fù)制出XPath松忍,如下圖:
獲取XPath.gif

Copy完XPath之后,我們可以貼出來(lái)看看XPath://*[@id="content"]/div[1]/div[1]/div[1]/div/h3/a
然后在Chrome的Console里面輸入:

$x('//*[@id="content"]/div[1]/div[1]/div[1]/div/h3/a')

我們看看能得到什么:

抓取單個(gè)a標(biāo)簽

只有一個(gè)a鏈接筷厘,可是我們要獲取的是整個(gè)列表鸣峭,這與我們的需求不符宏所,那么如何理解這句XPath代表的含義呢,我們需要查看下XPath的語(yǔ)法:http://www.w3school.com.cn/xpath/xpath_syntax.asp摊溶。
了解語(yǔ)法后爬骤,我們了解到XPath路勁(//[@id="content"]/div[1]/div[1]/div[1]/div/h3/a)指定了具體的某個(gè)div,我們只要修改下就好:'//[@id="content"]/div[1]/div[1]/div/div/h3/a'莫换,重新在Console里面輸入:

$x('//*[@id="content"]/div[1]/div[1]/div/div/h3/a')

這時(shí)候得到的就是整個(gè)列表的a鏈接了:

抓取列表a標(biāo)簽

拿到詳情頁(yè)的鏈接后霞玄,接下來(lái)我們要抓取正文內(nèi)容,打開詳情頁(yè):http://news.southcn.com/china/content/2017-12/26/content_179881431.htm
正文內(nèi)容

和之前列表一樣拉岁,獲取這幾個(gè)內(nèi)容的XPath

  • 標(biāo)題://*[@id="article_title"]
  • 時(shí)間://*[@id="pubtime_baidu"]
  • 來(lái)源://*[@id="source_baidu"]
  • 正文://*[@id="content"]
    ok坷剧,現(xiàn)在我們可以抓取新聞了。

問題點(diǎn)匯總

抓取思路沒有問題喊暖,而在實(shí)際抓取的過程中總是會(huì)遇到一些細(xì)節(jié)問題惫企,這里匯總下

HtmlAgilityPack

HtmlAgilityPack 提供了一個(gè)Load函數(shù),可以直接加載網(wǎng)頁(yè):

var url = "http://html-agility-pack.net/";
var web = new HtmlWeb();
var doc = web.Load(url);

但是實(shí)際使用中
我們發(fā)現(xiàn)很多網(wǎng)頁(yè)加載下來(lái)后陵叽,竟然是亂碼雅任,而導(dǎo)致亂碼的原因是不同的網(wǎng)站,采用的編碼不一樣咨跌,而Load函數(shù)并沒有設(shè)置編碼的地方……
所以果斷放棄Load沪么,自己寫代碼加載網(wǎng)頁(yè)Html:

private string GetHtml(string url,string encoding)
        {
            using (var client = new WebClient())
            {
                client.Encoding = Encoding.GetEncoding(encoding);
                var html = client.DownloadString(url);
                return html;
            }
        }

同一個(gè)站點(diǎn)的XPath也會(huì)不一樣

很多網(wǎng)站的新聞詳情頁(yè)會(huì)采用不同的模板來(lái)顯示,比如說視頻+正文锌半、圖片幻燈片+正文禽车、正文等不同的組合方式。而這個(gè)時(shí)候要正確抓取數(shù)據(jù)刊殉,就需要同時(shí)記錄多個(gè)XPath殉摔,做好非空判斷,挨次抓取记焊。

正文中的腳本處理

有些網(wǎng)站會(huì)在正文中嵌入廣告腳本逸月,而這個(gè)時(shí)候抓取這些腳本顯然對(duì)我們沒什么幫助,所以要對(duì)正文內(nèi)容過濾下遍膜,去除所有的腳本:

            var articleContent = contentDoc.InnerHtml;
            //移除正文中的script腳本
            Regex rRemScript = new Regex(@"<script[^>]*>[\s\S]*?</script>");
            articleContent = rRemScript.Replace(articleContent, "");
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末碗硬,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子瓢颅,更是在濱河造成了極大的恐慌恩尾,老刑警劉巖,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件挽懦,死亡現(xiàn)場(chǎng)離奇詭異翰意,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門冀偶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)醒第,“玉大人,你說我怎么就攤上這事进鸠〕砺” “怎么了?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵堤如,是天一觀的道長(zhǎng)蒲列。 經(jīng)常有香客問我窒朋,道長(zhǎng)搀罢,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任侥猩,我火速辦了婚禮榔至,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘欺劳。我一直安慰自己唧取,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布划提。 她就那樣靜靜地躺著枫弟,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鹏往。 梳的紋絲不亂的頭發(fā)上淡诗,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音伊履,去河邊找鬼韩容。 笑死,一個(gè)胖子當(dāng)著我的面吹牛唐瀑,可吹牛的內(nèi)容都是我干的群凶。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼哄辣,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼请梢!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起力穗,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤溢陪,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后睛廊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體形真,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了咆霜。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片邓馒。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖蛾坯,靈堂內(nèi)的尸體忽然破棺而出光酣,到底是詐尸還是另有隱情,我是刑警寧澤脉课,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布救军,位于F島的核電站,受9級(jí)特大地震影響倘零,放射性物質(zhì)發(fā)生泄漏唱遭。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一呈驶、第九天 我趴在偏房一處隱蔽的房頂上張望拷泽。 院中可真熱鬧,春花似錦袖瞻、人聲如沸司致。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)脂矫。三九已至,卻和暖如春霉晕,著一層夾襖步出監(jiān)牢的瞬間庭再,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工娄昆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留佩微,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓萌焰,卻偏偏與公主長(zhǎng)得像哺眯,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子扒俯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348