前言
上篇:在手把手叫你用R語言制作網(wǎng)絡(luò)爬蟲機(jī)器人(一)中我們已經(jīng)把整個(gè)新聞所有鏈接的URL全部解析到R里面或者以html的文件格式,下載到電腦上了,下面我們就講講怎么用正則表達(dá)式來進(jìn)行信息的提取。在這里我們第一步就是看看網(wǎng)頁的源代碼,首先要申明一點(diǎn),正則表達(dá)式之所以難,是因?yàn)楸仨氁页鏊栊畔⒌姆?hào)特征,以符號(hào)特征來進(jìn)行信息提取,而且必須要觀察所有網(wǎng)頁的共同特征,這是我們要在現(xiàn)實(shí)項(xiàng)目中積聚的經(jīng)驗(yàn)來判斷,因?yàn)槲医裉煊玫氖潜銛y電腦,另外一臺(tái)電腦在做遺傳算法的實(shí)驗(yàn),所以可能沒有上次用單位電腦那么性能好,所以不足之處請大家見諒。
我們隨便打開一個(gè)新聞鏈接?,F(xiàn)在不管是谷歌瀏覽器或者是IE瀏覽器點(diǎn)擊右鍵都有查看源代碼一項(xiàng),所以我們先點(diǎn)開網(wǎng)頁,右鍵查看源代碼。在這里我們要看的源代碼網(wǎng)頁為/10000/10276/ 
我們可以看見,源代碼就是這樣的,當(dāng)然沒顯示完,現(xiàn)在我們需要找到的就是我們所需要的信息,他們包含在源代碼的后面  我們觀察他們的特點(diǎn),所有漢字信息都包含在“ONT-FAMILY: 仿宋,仿宋_GB2312; FONT-SIZE: 14pt"> <font style="FONT-FAMILY: 黑體"> </font></span><span style="FONT-FAMILY: 黑體; FONT-SIZE: 14pt">”這個(gè)符號(hào)之后,當(dāng)然我們還需要提取標(biāo)題,標(biāo)題我們可以看見總是在“class="moji_f">”這個(gè)符號(hào)之后,而我們所要看的日期都在"border-bottom:#CCC 1px solid;">“這個(gè)符號(hào)之后,所以大致我們提取的文本信息就是這樣的,這樣的規(guī)律對于每一個(gè)鏈接都有效,因?yàn)槭峭瑯拥恼Z言寫的網(wǎng)頁,只要把規(guī)律找到我們不必?fù)?dān)心其他的會(huì)不會(huì)以同樣的規(guī)律存在,當(dāng)然在用正則表達(dá)式的時(shí)候我們還要進(jìn)一步調(diào)試代碼以便于他們更好的能以只管的方式表現(xiàn)出來,對于一些文件里存在照片的我們會(huì)在以后相信討論。
所謂的正則表達(dá)式是通過龐大的復(fù)雜的只有電腦才懂的一堆符號(hào)里提取我們所要的信息的語法,適用于很多種語言這里我們看看最常用的幾個(gè)(來源百度百科),大家要想了解可以去查看專門的書籍,這里不再重復(fù)。
d 匹配一個(gè)數(shù)字字符。等價(jià)于[0-9]。grep 要加上-P,perl正則支持 \D 匹配一個(gè)非數(shù)字字符。等價(jià)于[^0-9]。grep要加上-P,perl正則支持 \f 匹配一個(gè)換頁符。等價(jià)于\x0c和\cL。 \n 匹配一個(gè)換行符。等價(jià)于\x0a和\cJ。 \r 匹配一個(gè)回車符。等價(jià)于\x0d和\cM。 \s 匹配任何不可見字符,包括空格、制表符、換頁符等等。等價(jià)于[ \f\n\r\t\v]。 \S 匹配任何可見字符。等價(jià)于[^ \f\n\r\t\v]。 \t 匹配一個(gè)制表符。等價(jià)于\x09和\cI。 \v 匹配一個(gè)垂直制表符。等價(jià)于\x0b和\cK。 \w 匹配包括下劃線的任何單詞字符。類似但不等價(jià)于“[A-Za-z0-9_]”,這里的"單詞"字符使用Unicode字符集。 \W 匹配任何非單詞字符。等價(jià)于“[^A-Za-z0-9_]”。 \xn 匹配n,其中n為十六進(jìn)制轉(zhuǎn)義值。十六進(jìn)制轉(zhuǎn)義值必須為確定的兩個(gè)數(shù)字長。例如,“\x41”匹配“A”?!癨x041”則等價(jià)于“\x04&1”。正則表達(dá)式中可以使用ASCII編碼。 \num 匹配num,其中num是一個(gè)正整數(shù)。對所獲取的匹配的引用。例如,“(.)\1”匹配兩個(gè)連續(xù)的相同字符。 \n 標(biāo)識(shí)一個(gè)八進(jìn)制轉(zhuǎn)義值或一個(gè)向后引用。如果\n之前至少n個(gè)獲取的子表達(dá)式,則n為向后引用。否則,如果n為八進(jìn)制數(shù)字(0-7),則n為一個(gè)八進(jìn)制轉(zhuǎn)義值。 \nm 標(biāo)識(shí)一個(gè)八進(jìn)制轉(zhuǎn)義值或一個(gè)向后引用。如果\nm之前至少有nm個(gè)獲得子表達(dá)式,則nm為向后引用。如果\nm之前至少有n個(gè)獲取,則n為一個(gè)后跟文字m的向后引用。如果前面的條件都不滿足,若n和m均為八進(jìn)制數(shù)字(0-7),則\nm將匹配八進(jìn)制轉(zhuǎn)義值nm。 \nml 如果n為八進(jìn)制數(shù)字(0-7),且m和l均為八進(jìn)制數(shù)字(0-7),則匹配八進(jìn)制轉(zhuǎn)義值nml。 \un 匹配n,其中n是一個(gè)用四個(gè)十六進(jìn)制數(shù)字表示的Unicode字符。例如,\u00A9匹配版權(quán)符號(hào)(©)。 \p{P} 小寫 p 是 property 的意思,表示 Unicode 屬性,用于 Unicode 正表達(dá)式的前綴。中括號(hào)內(nèi)的“P”表示Unicode 字符集七個(gè)字符屬性之一:標(biāo)點(diǎn)字符。 其他六個(gè)屬性: L:字母; M:標(biāo)記符號(hào)(一般不會(huì)單獨(dú)出現(xiàn)); Z:分隔符(比如空格、換行等); S:符號(hào)(比如數(shù)學(xué)符號(hào)、貨幣符號(hào)等); N:數(shù)字(比如阿拉伯?dāng)?shù)字、羅馬數(shù)字等); C:其他字符。
這里我們所用語言為R,本質(zhì)上來說是S高級語言,所以也適用大部分正則表達(dá)式,下面我們就需要構(gòu)建正則表達(dá)式來提取我們所需要的信息。
三、用R構(gòu)建正則表達(dá)式來提取信息因?yàn)樾畔⒘刻嘁还步馕隽?830個(gè)源代碼我們這里就以第一個(gè)到第三個(gè)為例,剩下的以同樣方法處理就可以。
parsefile<-a t<-list(NULL) length(t)=3 for(i in 1:3){ t[[i]]<-parsefile[[i]] } m<-lapply(t,function(t) str_extract(t,"14pt\">.+\\w+|moji_f\">.+\\w+|1px solid;\">.+\\w+")) #################這里我們寫的正則表達(dá)式為在"14pt\">以后出現(xiàn)的文字文本\\w這個(gè)在正則表達(dá)式里為文本的意思,| 這個(gè)豎橫表達(dá)或者的意思通過上面的我們說的我們可以知道m(xù)oji_f\ 后面的是題目,1px solid;\">后面的是出處和日期########### b<-lapply(m,function(m) m[-which(is.na(m))]) ######因?yàn)檎齽t表達(dá)式會(huì)把沒用用的去掉產(chǎn)生NA所以這步我們?nèi)サ鬘A####### b
運(yùn)行代碼我們可以得到  可以看到我們已經(jīng)提取了我們所需要的結(jié)果(因?yàn)榻仄猎驔]有顯示完),但是還有部分字符沒有去掉,所以我們還得調(diào)試我們代碼: h<-lapply(b,function(b) str_extract(b,">.+\\w+|仿宋.+\\w+")) #######################一步步除掉我們不需要的字符,初學(xué)者特別要一步一步來#### k<-lapply(h,function(h) str_replace_all(h,pattern="</span><span style=\"FONT-FAMILY: 仿宋,仿宋_GB2312; FONT-SIZE: 14pt\">|</span>|<span>|</td|>|</p", replacement="")) #######################當(dāng)我們發(fā)現(xiàn)我們不能出去</span>等字樣的字符時(shí)候我們就要選擇str_replace_all函數(shù)取替換他們把他們替換成空值,我們輸出看看######## k
運(yùn)行結(jié)果為:  可以看見我們要的新聞信息出來了在這里這里除了第二個(gè)文件比較正常(大部分都是這樣的文件),第一個(gè)文件是有空格符和黑體標(biāo)簽,第三個(gè)文件有圖片所以有<img border=\"0\" src=\"/ewebeditor/uploadfile/20170401091612648.jpg\" style=\"display: block;margin:0 auto;\"</img"這樣的格式,我們暫且保留圖片格式,因?yàn)橐院笪覀儠?huì)利用這個(gè)下載圖片。  就是html格式里空格的意思,我們用以下命令刪除掉,但是“<font style=\"FONT-FAMILY: 黑體\" </font<span style=\"FONT-FAMILY: 黑體; FONT-SIZE: 14pt\”這一部分我始終沒有去掉的辦法,以后我去掉了會(huì)添加上來。 j<-lapply(k,function(k) gsub("([  ])", "", k)) j
結(jié)果為:  可以看見我們除掉空字符了 接下來我們把弄好的第三個(gè)新聞輸出看看 for (i in 1:3) { write.table(j[[i]],paste('file',i,'.txt',sep=''),quote = FALSE,row.names = FALSE,col.names = FALSE) }
依次打開三個(gè)文件看看
  
轉(zhuǎn)成txt文件是因?yàn)槲覀兘酉聛硪鰐xt mining 分析便于寫入,如果只是想爬取文件那我們可以轉(zhuǎn)換為doc格式: for (i in 1:3) { write.table(j[[i]],paste('file',i,'.doc',sep=''),quote = FALSE,row.names = FALSE,col.names = FALSE) }

我們打開看看    接下來我們把代碼串聯(lián)起來,輸出所有文件 parsefile<-a m<-lapply(parsefile,function(parsefile) str_extract(parsefile,"14pt\">.+\\w+|moji_f\">.+\\w+|1px solid;\">.+\\w+")) b<-lapply(m,function(m) m[-which(is.na(m))]) h<-lapply(b,function(b) str_extract(b,">.+\\w+|仿宋.+\\w+")) k<-lapply(h,function(h) str_replace_all(h,pattern="</span><span style=\"FONT-FAMILY: 仿宋,仿宋_GB2312; FONT-SIZE: 14pt\">|</span>|<span>|</td|>|</p", replacement="")) j<-lapply(k,function(k) gsub("([  ])", "", k)) for (i in 1:2830) { write.table(j[[i]],paste('file',i,'.doc',sep=''),quote = FALSE,row.names = FALSE,col.names = FALSE) }
我們以第三個(gè)文件圖片格式下載為基礎(chǔ)來講解,
我們檢查新聞鏈接里圖片地址(點(diǎn)擊圖片右鍵復(fù)制地址),接下來我們又來找規(guī)律 /ewebeditor/u 源代碼里圖片地址為  藍(lán)色的部分為圖片地址,但是真正的地址要加上基本url,http://www./,所以我們可以寫出相應(yīng)的正則表達(dá)式,從服務(wù)器里抓取圖片(以上面舉例的第三個(gè)文件為基礎(chǔ)) photo<-str_extract(t[[3]],"ewebeditor/uploadfile/.+\\w+.jpg") photo<-photo[-which(is.na(photo))] photo

我們可以看見提取了服務(wù)器圖片地址再把它結(jié)合基本url,就可以得到完整的圖片下載地址 photourl<-str_c(baseurl,"/",photo)
 于是我們得到了一個(gè)完整的圖片服務(wù)器下載地址我們下載來看看
download.file( photourl,"photo1.jpg",mode="wb") ##############這里可以保存為任何格式的圖片文件不光jpg####
得到   我們可以看見圖片文件就可以下載下來了, 我們把以上代碼應(yīng)用到整個(gè)2830個(gè)html photo<-str_extract(parsefile,"ewebeditor/uploadfile/.+\\w+.jpg") photo<-photo[-which(is.na(photo))] photo
 得到293個(gè)url photourl<-str_c(baseurl,"/",photo)
 我們下載這293張圖片 for (i in 1:293) { download.file(photourl[i],paste('photo',i,'.jpg',sep=''),mode="wb") }
 大家可以看見293張圖片全部下載到文件里了。
|