通过WebMagic认识正则表达式和XPATH

来源:互联网 发布:伊藤网络超市 编辑:程序博客网 时间:2024/06/05 12:42

最近在自学JAVA的过程中,偶然想到了做个爬虫程序,经过简单的对比,发现了WebMagic这个库,在使用库的过程中因为涉及到正则表达式和XPATH,所以做个笔记,记录一下,否则稍微过段时间不看就忘记了。以内涵社区为例,打开内涵社区,然后右键“检查”(Chrome浏览器,得到如下html,这里只截取其中一部分作为示例)

<div class="detail-wrapper"><div class="header "><a href="http://neihanshequ.com/user/50634720394//">![](http://upload-images.jianshu.io/upload_images/2761682-5711d755117472ef?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)<div class="name-time-wrapper left"><span class="name">我是MC秀芹</span><span class="time timeago" title="2017-07-19 07:43:53000">07-19 07:43</span></div></a></div><div class="content-wrapper"><a target="_blank" class="image share_url" href="http://neihanshequ.com/p63821171027/" data-group-id="63821171027" ><div class="upload-txt no-mb"><h1 class="title"><p>今年18岁的我,年纪轻轻月薪就已经达到1500了,加上提成满勤再加上我天生的睿智头脑,平常帮客人拿下拖鞋点下烟得点小费可以拿到2200,觉得自己这几年过得也不容易,现在这么有钱,觉得不知道怎么花了,开始花钱大手大脚了,以前网吧包夜都是自己带瓶水,现在敢喝冰红茶了,还是一晚上买两瓶,甚至吃泡面要加两根肠,我觉得现在有点迷失自我,有什么办法!能回到初心!</p></h1></div></a></div>

然后,开始我们的爬虫程序:
创建一个类GithubRepoPageProcessor(为什么叫Github...因为跟着写demo的时候创建的,懒得修改了)继承PageProcessor,并实现方法:

public class GithubRepoPageProcessor implements PageProcessor {    public static final String URL_LIST = "http://neihanshequ.com/.*";    private Site site = Site.me().setRetryTimes(3).setSleepTime(1000);    public void process(Page page) {        //文章页        Object s0 = page.getHtml().xpath("//div[@class='detail-wrapper']//div[@class='header ']/a/img/@src");        Object s1 = page.getHtml().xpath("//div[@class='detail-wrapper']//div[@class='header ']/a/div/span[@class='name']/text()");        Object s2 = page.getHtml().xpath("//div[@class='detail-wrapper']//div[@class='header ']/a/div/span[@class='time timeago']/text()");        Object s3 = page.getHtml().xpath("//div[@class='detail-wrapper']//div[@class='content-wrapper']//h1[@class='title']/p/text()");        if (s0 != null                &&s1 != null                && s2 != null                && s3 != null) {            page.putField("头像", s0);            page.putField("用户名", s1);            page.putField("发表时间", s2);            page.putField("发表内容", s3);        }        page.addTargetRequests(page.getHtml().links().regex(URL_LIST).all());    }    public Site getSite() {        return site;    }}

好,那么这里就要用正则和XPATH提取我们需要的内容了:

先来看下正则表达式的常用字符:

.        任意字符除换行符\w       字母、数字、下划线、汉字\d       数字\b       标注单词的开始、结束位置^        标注开始位置$        标注结束位置*        重复零次或更多次+        重复一次或更多次?        重复零次或一次{n}      重复n次{n,}     重复n次或更多次{n,m}    重复n到m次[0-9]           等同于\d[a-z]           a-z中的任意一个字母[aeiou]         aeiou中的任意一个字母[0-9 a-z A-Z]   等同于\w|        分支(从左到右依次执行,匹配依次后,后面的不再匹配)()       分组(表达式分组)\W    不是字母、数字、下划线、汉字\S    不是空白符\D    非数字\B    不是单词开头、结束的位置[^x]    除了x以外的任意字符[^aeiou]  除了aeiou这几个字母以外的任意字符(?<=exp) 掐头(?=exp)  去尾(?<!exp)  禁止前面包含字符(?!exp)    禁止后面包含字符

接下来使用上面的html文件依次举例:
1、获取所有的数字

\d+

扩展例子:

匹配手机号(匹配13、15、17、18开头的11位手机号):^1[3578]\d{9}$匹配QQ号(匹配5-11位的QQ号)^\d{5,11}$匹配126邮箱(6-20个字节的用户名)[a-zA-Z][a-zA-Z0-9]{5,19}@126.com$匹配IP地址(网上有其他的正则,认为01.01.0.1算是正确的IP,但是我不喜欢,所以写个这样的)(1\d\d|2[0-4]\d|25[0-4]|^[1-9])\.((1\d\d|2[0-4]\d|25[0-4]|[0-9])\.){2}(1\d\d|2[0-4]\d|25[0-4]|[0-9])

2、获取所有p标签里的内容

正则:(?<=<p>).*(?=</p>)XPATH:精确路径定位://div[@class='detail-wrapper']//div[@class='upload-txt  no-mb']//h1/p/text()简单定位://h1[@class='title']/p/text()

3、获取所有的href内容

正则:(?<=href=").*(?=/")XPATH:精确路径定位://div[@class='detail-wrapper']//a/@href简单定位://a[@class='image share_url']/@href

分析GithubRepoPageProcessor里面的内容:

//匹配http://neihanshequ.com为前缀的所有网址public static final String URL_LIST = "http://neihanshequ.com/.*";//获取当前html页面的所有class名称为detail-wrapper的div下的所有class名称为header下的a标签里面的img标签中的src地址Object s0 =page.getHtml().xpath("//div[@class='detail-wrapper']//div[@class='header ']/a/img/@src")//获取上述前缀的a标签下的div下的class名为name的span标签里面的内容Object s1 =page.getHtml().xpath("//div[@class='detail-wrapper']//div[@class='header ']/a/div/span[@class='name']/text()")//获取class名为time timeago的span标签里的内容Object s2 =page.getHtml().xpath("//div[@class='detail-wrapper']//div[@class='header ']/a/div/span[@class='time timeago']/text()")//获取p标签下的内容Object s3 =page.getHtml().xpath("//div[@class='detail-wrapper']//div[@class='content-wrapper']//h1[@class='title']/p/text()")然后把获取到的内容输出到控制台:page.putField("头像", s0);            page.putField("用户名", s1);            page.putField("发表时间", s2);            page.putField("发表内容", s3);

创建MainApp写入main方法并调用运行

public class MainApp {    public static void main(String[] args) {        System.out.println("开始爬取...");        Spider.create(new GithubRepoPageProcessor()).addUrl("http://neihanshequ.com").thread(5).run();    }}

最终效果:


WX20170720-151802.png


作者:独箸
链接:http://www.jianshu.com/p/3d9e5bb9f7b0
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
原创粉丝点击