手把手教你用R语言制作网络爬虫机器人(二)

欢迎关注天善智能,我们是专注于商业智能BI,人工智能AI,大数据分析与挖掘领域的垂直社区,学习,问答、求职一站式搞定!

对商业智能BI、大数据分析挖掘、机器学习,python,R等数据领域感兴趣的同学加微信:tstoutiao,邀请你进入数据爱好者交流群,数据爱好者们都在这儿。

作者:梁凯  R语言中文社区专栏作者

知乎ID:https://www.zhihu.com/people/liang-kai-77-98

前言

上篇:手把手教你用R语言制作网络爬虫机器人(一)讲到,我们已经把整个新闻所有链接的URL全部解析到R里面或者以html的文件格式,下载到电脑上了,下面我们就讲讲怎么用正则表达式来进行信息的提取。在这里我们第一步就是看看网页的源代码,首先要申明一点,正则表达式之所以难,是因为必须要找出所需信息的符号特征,以符号特征来进行信息提取,而且必须要观察所有网页的共同特征,这是我们要在现实项目中积聚的经验来判断,因为我今天用的是便携电脑,另外一台电脑在做遗传算法的实验,所以可能没有上次用单位电脑那么性能好,所以不足之处请大家见谅。

一、观察所要提取网页源代码

我们随便打开一个新闻链接。现在不管是谷歌浏览器或者是IE浏览器点击右键都有查看源代码一项,所以我们先点开网页,右键查看源代码。在这里我们要看的源代码网页为gzz.gov.cn/10000/10276/

我们可以看见,源代码就是这样的,当然没显示完,现在我们需要找到的就是我们所需要的信息,他们包含在源代码的后面

3901436-b7bb6ceb1d1120e5

我们观察他们的特点,所有汉字信息都包含在“ONT-FAMILY: 仿宋,仿宋_GB2312; FONT-SIZE: 14pt">&nbsp;&nbsp;&nbsp;<font style="FONT-FAMILY: 黑体"> </font></span><span style="FONT-FAMILY: 黑体; FONT-SIZE: 14pt">”这个符号之后,当然我们还需要提取标题,标题我们可以看见总是在“class="moji_f">”这个符号之后,而我们所要看的日期都在"border-bottom:#CCC 1px solid;">“这个符号之后,所以大致我们提取的文本信息就是这样的,这样的规律对于每一个链接都有效,因为是同样的语言写的网页,只要把规律找到我们不必担心其他的会不会以同样的规律存在,当然在用正则表达式的时候我们还要进一步调试代码以便于他们更好的能以只管的方式表现出来,对于一些文件里存在照片的我们会在以后相信讨论。

二、正则表达式的提取方式

所谓的正则表达式是通过庞大的复杂的只有电脑才懂的一堆符号里提取我们所要的信息的语法,适用于很多种语言这里我们看看最常用的几个(来源百度百科),大家要想了解可以去查看专门的书籍,这里不再重复。

d

匹配一个数字字符。等价于[0-9]。grep 要加上-P,perl正则支持

\D

匹配一个非数字字符。等价于[^0-9]。grep要加上-P,perl正则支持

\f

匹配一个换页符。等价于\x0c和\cL。

\n

匹配一个换行符。等价于\x0a和\cJ。

\r

匹配一个回车符。等价于\x0d和\cM。

\s

匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。

\S

匹配任何可见字符。等价于[^ \f\n\r\t\v]。

\t

匹配一个制表符。等价于\x09和\cI。

\v

匹配一个垂直制表符。等价于\x0b和\cK。

\w

匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]”,这里的"单词"字符使用Unicode字符集。

\W

匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。

\xn

匹配n,其中n为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。

\num

匹配num,其中num是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符。

\n

标识一个八进制转义值或一个向后引用。如果\n之前至少n个获取的子表达式,则n为向后引用。否则,如果n为八进制数字(0-7),则n为一个八进制转义值。

\nm

标识一个八进制转义值或一个向后引用。如果\nm之前至少有nm个获得子表达式,则nm为向后引用。如果\nm之前至少有n个获取,则n为一个后跟文字m的向后引用。如果前面的条件都不满足,若n和m均为八进制数字(0-7),则\nm将匹配八进制转义值nm。

\nml

如果n为八进制数字(0-7),且m和l均为八进制数字(0-7),则匹配八进制转义值nml。

\un

匹配n,其中n是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。

\p{P}

小写 p 是 property 的意思,表示 Unicode 属性,用于 Unicode 正表达式的前缀。中括号内的“P”表示Unicode 字符集七个字符属性之一:标点字符。

其他六个属性:

L:字母;

M:标记符号(一般不会单独出现);

Z:分隔符(比如空格、换行等);

S:符号(比如数学符号、货币符号等);

N:数字(比如阿拉伯数字、罗马数字等);

C:其他字符。

这里我们所用语言为R,本质上来说是S高级语言,所以也适用大部分正则表达式,下面我们就需要构建正则表达式来提取我们所需要的信息。

三、用R构建正则表达式来提取信息

因为信息量太多一共解析了2830个源代码我们这里就以第一个到第三个为例,剩下的以同样方法处理就可以。

parsefile<-a

t<-list(NULL)

length(t)=3

for(iin1:3){

t[[i]]<-parsefile[[i]]

}

m<-lapply(t,function(t) str_extract(t,"14pt\">.+\\w+|moji_f\">.+\\w+|1px solid;\">.+\\w+"))

#################这里我们写的正则表达式为在"14pt\">以后出现的文字文本\\w这个在正则表达式里为文本的意思,| 这个竖横表达或者的意思通过上面的我们说的我们可以知道moji_f\

后面的是题目,1px solid;\">后面的是出处和日期###########

b<-lapply(m,function(m) m[-which(is.na(m))])

######因为正则表达式会把没用用的去掉产生NA所以这步我们去掉NA#######

b

运行代码我们可以得到

可以看到我们已经提取了我们所需要的结果(因为截屏原因没有显示完),但是还有部分字符没有去掉,所以我们还得调试我们代码:

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=""))

#######################当我们发现我们不能出去等字样的字符时候我们就要选择str_replace_all函数取替换他们把他们替换成空值,我们输出看看########

k

运行结果为:

可以看见我们要的新闻信息出来了在这里这里除了第二个文件比较正常(大部分都是这样的文件),第一个文件是有空格符和黑体标签,第三个文件有图片所以有<img border=\"0\" src=\"/ewebeditor/uploadfile/20170401091612648.jpg\" style=\"display: block;margin:0 auto;\"</img"这样的格式,我们暂且保留图片格式,因为以后我们会利用这个下载图片。

&nbsp;&nbsp;&nbsp就是html格式里空格的意思,我们用以下命令删除掉,但是“<font style=\"FONT-FAMILY: 黑体\" </font<span style=\"FONT-FAMILY: 黑体; FONT-SIZE: 14pt\”这一部分我始终没有去掉的办法,以后我去掉了会添加上来。

j<-lapply(k,function(k)gsub("([&nbsp;&nbsp;&nbsp])","", k))

j

结果为:

可以看见我们除掉空字符了

接下来我们把弄好的第三个新闻输出看看

for(iin1:3) {

write.table(j[[i]],paste('file',i,'.txt',sep=''),quote = FALSE,row.names = FALSE,col.names = FALSE)

}

依次打开三个文件看看

3901436-9c4219832865cb7a
3901436-d71aaea7ee81ded1
3901436-7b36fb3fd78c62cf

转成txt文件是因为我们接下来要做txt mining 分析便于写入,如果只是想爬取文件那我们可以转换为doc格式:

for(iin1:3) {

write.table(j[[i]],paste('file',i,'.doc',sep=''),quote = FALSE,row.names = FALSE,col.names = FALSE)

}

我们打开看看

接下来我们把代码串联起来,输出所有文件

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("([&nbsp;&nbsp;&nbsp])","", k))

for(iin1:2830) {

write.table(j[[i]],paste('file',i,'.doc',sep=''),quote = FALSE,row.names = FALSE,col.names = FALSE)

}

四、图片格式的下载

我们以第三个文件图片格式下载为基础来讲解,

我们检查新闻链接里图片地址(点击图片右键复制地址),接下来我们又来找规律

gzz.gov.cn/ewebeditor/u

源代码里图片地址为

蓝色的部分为图片地址,但是真正的地址要加上基本url,http://www.gzz.gov.cn/,所以我们可以写出相应的正则表达式,从服务器里抓取图片(以上面举例的第三个文件为基础)

photo<-str_extract(t[[3]],"ewebeditor/uploadfile/.+\\w+.jpg")

photo<-photo[-which(is.na(photo))]

photo

3901436-232292411ef71f13

我们可以看见提取了服务器图片地址再把它结合基本url,就可以得到完整的图片下载地址

photourl<-str_c(baseurl,"/",photo)

于是我们得到了一个完整的图片服务器下载地址我们下载来看看

download.file( photourl,"photo1.jpg",mode="wb")

##############这里可以保存为任何格式的图片文件不光jpg####

得到

3901436-4ee8afd4b37b3f8d

我们可以看见图片文件就可以下载下来了,

我们把以上代码应用到整个2830个html

photo<-str_extract(parsefile,"ewebeditor/uploadfile/.+\\w+.jpg")

photo<-photo[-which(is.na(photo))]

photo

得到293个url

photourl<-str_c(baseurl,"/",photo)

我们下载这293张图片

for(iin1:293) {

download.file(photourl[i],paste('photo',i,'.jpg',sep=''),mode="wb")

}

大家可以看见293张图片全部下载到文件里了。

往期精彩:

不加载任何包,手撕一个R语言版BP神经网络模型

用R语言实现密度聚类dbscan

R中的子集选取运算符

公众号后台回复关键字即可学习

回复 爬虫            爬虫三大案例实战

回复 Python       1小时破冰入门

回复 数据挖掘     R语言入门及数据挖掘

回复 人工智能     三个月入门人工智能

回复 数据分析师  数据分析师成长之路 

回复 机器学习     机器学习的商业应用

回复 数据科学     数据科学实战

回复 常用算法     常用数据挖掘算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值