CSDN爬虫(五)——CSDN用户(所有)爬取+常用爬虫正则整理
2017-10-23 16:48
330 查看
CSDN爬虫(五)——CSDN用户(所有)爬取+常用爬虫正则整理
说明
开发环境:jdk1.7+myeclipse10.7+win74bit+mysql5.5+webmagic0.5.2+jsoup1.7.2爬虫框架:webMagic
建议:建议首先阅读webMagic的文档,再查看此系列文章,便于理解,快速学习:http://webmagic.io/
开发所需jar下载(不包括数据库操作相关jar包):点我下载
该系列文章会省略webMagic文档已经讲解过的相关知识。
概述
我们会从CSDN个人中心出发,首先爬取一个用户的个人信息。然后根据该用户的好友关系去爬取好友信息。依次类推,爬取所用用户。爬取CSDN所有用户是根据“粉丝、关注”去爬取“粉丝、关注”,必然会涉及到“死循环”。到后期肯定会出现大量“脏数据”(重复数据),就要考虑到过滤脏数据的问题。
虽然用webMagic框架爬虫会用到大量的正则表达式,并且爬虫类的正则在网上也很少能找到资料,但是也是比较固定。
CSDN用户(所有)爬取代码预览
package com.wgyscsf.spider; import java.util.List; import org.jsoup.select.Elements; import us.codecraft.webmagic.Page; import us.codecraft.webmagic.Site; import us.codecraft.webmagic.Spider; import us.codecraft.webmagic.processor.PageProcessor; import us.codecraft.webmagic.selector.Html; import com.wgyscsf.utils.MyStringUtils; /** * @author 高远</n> * 编写日期 2016-9-24下午7:25:36</n> * 邮箱 wgyscsf@163.com</n> * 博客 http://blog.csdn.net/wgyscsf</n> * TODO</n> */ public class CsdnMineSpider implements PageProcessor { private final String TAG = CsdnMineSpider.class.getSimpleName(); private Site site = Site .me() .setDomain("my.csdn.net") .setSleepTime(1000) // 便于测试,休眠较长时间。 .setUserAgent( "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.65 Safari/537.31"); @Override public void process(Page page) { // 列表页: 这里进行匹配,匹配出列表页进行相关处理。 if ((page.getUrl()).regex("http://my.csdn.net/\\w+").match()) { // 获取最外层节点 // TODO:应该是get(1),不知道为什么 Elements mainElements = page.getHtml().getDocument() .getElementsByTag("div").get(2).children(); // 个人资料 Elements profileElements = mainElements.get(0).getElementsByTag( "div"); // 个人技能 Elements skillElements = mainElements.get(1) .getElementsByTag("div"); // 关系模块:关注和被关注 Elements relationElements = mainElements.get(2).getElementsByTag( "div"); // 获取用户id String id_mine = MyStringUtils.getLastSlantContent(skillElements .get(0).getElementsByTag("a").get(0).attr("href")); // 开始获取个人资料 String headImg = profileElements.get(0) .getElementsByClass("person-photo").get(0) .getElementsByTag("img").attr("src"); String fansNums = profileElements.get(0) .getElementsByClass("fans_num").get(0) .getElementsByTag("b").get(0).text(); String nickname = profileElements.get(0) .getElementsByClass("person-nick-name").get(0) .getElementsByTag("span").get(0).text(); // 这里只能精确到个人资料,没法继续分,因为好多用户该栏目只填写部分内容 String personDetail = profileElements.get(0) .getElementsByClass("person-detail").get(0).text(); // 开始组织个人资料,保存数据操作 System.out.println(TAG + ":用户id:" + id_mine + ",昵称:" + nickname + ",粉丝:" + fansNums + ",个人资料概述:" + personDetail + ",其它信息...."); // 当前爬取页面信息爬取结束,将当前页面设置为“跳过”,下次再加入爬虫队列,直接过滤,提高爬取效率。 page.setSkip(true); // 测试,看是否再被爬取。 page.addTargetRequest("http://my.csdn.net/wgyscsf"); /* * 核心部分,从关系模块出发,去遍历所有相关用户! */ // 开始获取关注与被关注以及访客的个人中心。同时加入爬虫队列。 String html = relationElements.get(0).html(); List<String> all = new Html(html) .xpath("//div[@class=\"mod_relations\"]").links().all(); // 加入到爬虫队列 page.addTargetRequests(all); } } @Override public Site getSite() { return site; } public static void main(String[] args) { Spider.create(new CsdnMineSpider()) .addUrl("http://my.csdn.net/wgyscsf").thread(1)// 便于测试,只开一个线程,正常爬起来,可以开15不成问题。 .pipeline(null) .run(); } }1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
关键代码解释
正则 http://my.csdn.net/\\w+"表示过滤出以
http://my.csdn.net/"开头的网址链接。不过该正则存在一定的问题,就是只对网址前面部分进行了限制,并没有对后面进行限制。只要以
http://my.csdn.net/"开头的网址全部会被加入到爬虫队列,存在大量的“脏数据”网址。比较合理的是:
http://my.csdn.net/"后面可以出现除了“/”的任意字符。正则的准确性直接影响到爬虫的效率,越准确越好。这里不再修改。
profileElements.get(0).getElementsByClass("person-detail").get(0).text();该代码片段是为了获取用户的个人资料,该资料比较多,包括行业、职业、地区(国、省、市、区等)、姓名等信息。经过分析没有好的依据对信息进行归类,这里只是获取粗略信息。经过分析,甚至说CSDN官方最开始对该块没有进行合理的安排,导致用户的信息没有统一的格式。
以下代码片段是该部分的核心代码,实现了递归式的爬取所有用户。
relationElements元素来自于
mainElements.get(2).getElementsByTag("div");,属于“关系模块”,包括关注的人和被关注的人以及访客信息。在这个模块中可以获取部分其它用户的id,只不过是部分的,最多只有6个人信息。CSDN官方没有提供获取所有粉丝或者关注者的信息。不过,只要这仅仅的用户信息,我们就可以爬取所有的用户。方便的是,顺便可以过滤掉“死鱼”用户(没有相互关系的用户)。
// 开始获取关注与被关注以及访客的个人中心。同时加入爬虫队列。 String html = relationElements.get(0).html(); List<String> all = new Html(html) .xpath("//div[@class=\"mod_relations\"]").links().all(); // 加入到爬虫队列 page.addTargetRequests(all);1
2
3
4
5
6
7
需要说明的是,爬取所有用户,其实不是一定要定位到“关系”模块。我们甚至可以简单粗暴的直接获取
http://my.csdn.net/user_id"中所用有效链接,直接加入到爬虫队列。到时候直接通过正则
http://my.csdn.net/\\w+"过滤出有效链接即可。代码如下:
// 直接取出该网页下的所有网址链接,简单粗暴,不用进行判断。 // 只要在进入爬取用户信息的时候加正则匹配即可。 // 但是会出现过多的“脏数据”,增加判断,影响爬取效率。 List<String> all = page.getHtml().links().all(); System.out.println(all);// 测试打印的网址链接 // 加入到爬虫队列 page.addTargetRequests(all);1
2
3
4
5
6
7
8
正如前文概述中所说,递归时的爬取用户信息,会出现大量已经爬取过的页面,我们需要“过滤”掉这些信息。核心的代码是
page.setSkip(true);,爬取之后,直接设置为“跳过”,下次爬取会直接跳过该链接。webMagic的作者对该方法的解释如下:
/**
Set whether to skip the result.
Result which is skipped will not be processed by Pipeline.
*
@param skip whether to skip the result
@return this
*/
过滤代码如下:
// 当前爬取页面信息爬取结束,将当前页面设置为“跳过”,下次再加入爬虫队列,直接过滤,提高爬取效率。 page.setSkip(true); // 测试,看是否再被爬取。 page.addTargetRequest("http://my.csdn.net/wgyscsf");1
2
3
4
5
爬取结果预览
爬取所有用户 爬取所有
http://my.csdn.net/user_id"内网址
常用爬虫正则
http://my.csdn.net/\\w+":过滤出所有以
http://my.csdn.net/开头的网址。
^http://blog.csdn.net/((?!/).)*$:过滤出以
http://blog.csdn.net/开头,并且后面不能再出现“/”的所有网址链接。
^http://blog.csdn.net/\\w+/article/list/[0-9]*[1-9][0-9]*$:过滤出
http://blog.csdn.net/后面是任意字符,并且紧接着
/article/list/,且
/article/list/后面只能是数字的所有网址链接。
http://blog.csdn.net/\\w+/article/details/\\w+:效果同上,只是最后允许任意字符,不仅仅限于数字。
测试正则的方式
Pattern pattern = Pattern .compile("^http://blog.csdn.net/\\w+/article/list/[0-9]*[1-9][0-9]*$"); Matcher matcher = pattern .matcher("http://blog.csdn.net/wgyscsf/article/list/32423"); boolean b = matcher.matches(); // 当条件满足时,将返回true,否则返回false System.out.println(b);1
2
3
4
5
6
7
8
操作代码(代码已全部迁移至github,欢迎star)
https://github.com/scsfwgy/WebMagic_CSDN_Demo
相关文章推荐
- CSDN爬虫(五)——CSDN用户(所有)爬取+常用爬虫正则整理
- 导出当前域内所有用户hash的技术整理
- 常用的PHP正则表达式整理
- 常用正则表达式整理
- 网上搜寻整理的常用的正则表达式
- 常用JS正则整理
- 常用的PHP正则表达式收集整理
- [整理] 常用正则表达式收集&勘误
- 日常收集整理php正则表达式(超常用)
- js常用事件整理—兼容所有浏览器
- PHP 常用正则表达式整理
- EditPlus常用正则表达式整理
- 【整理】常用正则表达式
- JavaScript正则表达式——常用正则表达式整理
- 常用cheat sheet 整理(正则、git、jquery、机器学习等等)
- 常用正则表达式整理
- 收集整理项目中常用到的正则表达式
- C#常用正则表达整理
- 常用正则表达式整理