模仿老师的代码开始自己的爬虫项目

模仿老师的代码开始自己的爬虫项目

写在前面

  • 这篇子博客主要是记录我写的三个爬虫得心得,主要把精力集中在第一个爬取什么值得买网站上了,剩下两个通过修改爬取信息和正则表达式,可以很快的运作起来
  • 我会运用一一讲解代码的形式来介绍为什么要这么做,或者这么做有什么作用(第一个例子)
  • 剩下,我爬取了十个左右的网站,因为代码大多数重复,所以我就简要介绍一下他们的不同之处

什么值得买 网站

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
var source_name = "什么值得买?";
var domain = 'https://post.smzdm.com';
var myEncoding = "utf-8";
var seedURL = 'https://post.smzdm.com';

var seedURL_format = "$('a')";//a-href,这是为了获取到源代码中所有a开头的链接
var regExp =/\/.\/.{8}\//;//获取a href的正则表达式


var interface_format = "$('h1.item-name').text()";//标题内容
var content_format = "$('.m-contant').text()";//正文内容

//下面是引环节,具体的讲解在我的另一篇:爬虫项目中引用的包极其用法有所讲解
var fs = require('fs');
var myRequest = require('request')
var myCheerio = require('cheerio')
var myIconv = require('iconv-lite')
require('date-utils');

//因为很多网站会防止爬虫,所以我们必须伪装成一个浏览器来防止屏蔽
var headers = {
'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.65 Safari/537.36'
}
//下面的代码块,我在request模块讲解时有所提及,这里略去不讲
function request(url, callback) {
var options = {
url: url,
encoding: null,
//proxy: 'http://x.x.x.x:8080',//过代理
headers: headers,
timeout: 10000 //多长时间没有反应,就不去理他了
}
myRequest(options, callback)
}

//下面的代码块的作用是搜索主网的源代码,找出符合条件的子网页的链接
request(seedURL,function (err,res,body) {
var html = myIconv.decode(body, myEncoding);
console.log(html);
//准备用cheerio解析html
var $ = myCheerio.load(html, { decodeEntities: true });
//定义一个子网页数组,然后让他把我想要的所有目标链接都写进去,这里,还没有做进一步筛选
var seedurl_news;
try{
seedurl_news = eval(seedURL_format);
} catch (e) { console.log('url列表所处的html块识别出错:' + e) };

//这里做了进一步筛选,搜索我们新闻链接数组中的每一个元素
seedurl_news.each(function (i,e) {
//定义一个子链接字符串
var myURL ="";
try{
var href = "";
//让href等于 <a href="https://post.smzdm.com/p/alpwnzve/" 源代码中href后面的字符串、
//也就是我们想要的子网站的链接
href = $(e).attr("href");
if(href.toLocaleString().indexOf('https://')>=0||href.toLocaleString().indexOf('http://')>=0)
//这里再做一个判断,如果成功,我们就让子链接等于href
myURL = href; //其他
} catch (e) { console.log('识别种子页面中的论坛链接出错:' + e) }
//同时,如果子链接是不复合我们的正则表达式的,那么,我们就需要遍历下一个。
if(!regExp.test(myURL))return;
//最后经过三层筛选,我们终于可以进一步读取了,这里用自己定义的newsGet函数
newsGet(myURL);//读取论坛页面
});
});
//下面是newsGet函数的具体内容
function newsGet(myURL) {
//首先做一个对myURL的访问
request(myURL,function (err,res,body) {
// 然后做一个转码
var html_news = myIconv.decode(body,myEncoding);
//用cheerio解析,并把我们需要的内容分别存给了各个$开头的内容
//关于$是怎么操作的,请看我的博客:爬虫项目中引用的包及其用法
var $ = myCheerio.load(html_news, { decodeEntities: true });
//进行到这一步,我们可以说已经把所有子页面中我们需要的
console.log("转码读取成功:" + myURL);
//然后就定义一个对象,把所有我们需要的信息都放到对象中的属性中去
var fetch = {}
fetch.url = myURL;
fetch.content = "";
fetch.crawltime = new Date();
fetch.source_encoding = myEncoding; //编码
fetch.source_name = source_name;
fetch.interface_format = eval(interface_format);
fetch.content = eval(content_format); //内容
//最后做一个json文件的存储,关于存储时遇到的问题,我再主博客的问题6有所介绍
var filename = source_name + "_" +(new Date()).valueOf() +".json";
// 存储json
fs.writeFileSync(filename, JSON.stringify(fetch));
});
}
  • 从下面开始的十一个网站,就是如法炮制一般,可以批量生产了,唯一要改动的,就是编码格式,正则表达式,还有更具不同网页源代码改变不同存储类型中的样式
  • 比如,同样是title_format 虎扑后面就是 #j_data 网易就是 h1 这种非常灵活,需要我们一一对照devtool

虎扑论坛

1
2
3
4
5
6
7
8
9
10
11
12
13
var source_name = "虎扑";
var domain = 'https://www.hupu.com/';
var myEncoding = "utf-8";
var seedURL = 'https://www.hupu.com/';

var seedURL_format = "$('a')";//a-href
var regExp =/\/\d+[.]html/;//获取a href的正则表达式

var title_format = "$('#j_data').text()";
var user_format ="$('.u').text()";
var content_format ="$('.quote-content').text()";
var title_format2 = "$('.headline').text()";
var content_format2 ="$('.artical-main-content').text()";

网易新闻

1
2
3
4
5
6
7
8
9
10
11
12
13
var source_name = "网易";
var domain = 'https://www.163.com/';
var myEncoding = "GBK";//
var seedURL = 'https://www.163.com/';

var seedURL_format = "$('a')";//a-href
var regExp =/\/\d{2}\/\d{4}\/\d{2}\/.+[.]html/;//获取a href的正则表达式

var article_source = "$('#ne_article_source').text()";
var title_format = "$('h1').text()";
var author ="$('.ep-editor').text()";
var content_format ="$('.post_text').text()";
var pubtime = "$('.post_time_source').text()";
  • 值得注意的是,网易的编码是GBK而不是utf-8如果以utf-8的编码格式这样把他存入数据库或者保存在json文件夹中,会出现乱码

示例

  • 只要改成myEncoding = “GBK”就可以完美规避这个问题

新浪

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var source_name = "新浪体育";
var domain = 'http://sports.sina.com.cn/';
var myEncoding = "utf-8";
var seedURL = 'http://sports.sina.com.cn/';

var seedURL_format = "$('a')";//a-href
var regExp =/\/.+\/\d{4}-\d{2}-\d{2}\/.+[.]shtml/;//获取a href的正则表达式

var title_format = "$('.main-title').text()";
var article_source = "$('.source ent-source').text()";
var content_format ="$('.article').text()";
var author ="$('.show_author').text()";
// var content_format2 ="$('.artical-main-content').text()";
var pubtime = "$('.date').text()";

东方财富

1
2
3
4
5
6
7
8
9
10
11
12
13
var source_name = "东方财富网";
var domain = 'https://www.eastmoney.com/';
var myEncoding = "utf-8";
var seedURL = 'https://www.eastmoney.com/';

var seedURL_format = "$('a')";//a-href
var regExp =/\/.\/\d+[.]html/;//获取a href的正则表达式

var title_format = "$('h1').text()";
var pubtime = "$('.time').text()";
// var article_source = "$('.source data-source').text()";
var content_format ="$('.Body').text()";
var author ="$('.res-edit').text()";

雪球财经

1
2
3
4
5
6
7
8
9
10
11
12
13
var source_name = "雪球财经";
var domain = 'https://xueqiu.com/';
var myEncoding = "utf-8";
var seedURL = 'https://xueqiu.com/';

var seedURL_format = "$('a')";//a-href
var regExp =/\/\d+\/\d{9}/;//获取a href的正则表达式

var title_format = "$('.article__bd__title').text()";
var pubtime = "$('.time').text()";
var article_source = "$('.source').text()";
var content_format ="$('.article__bd__detail').text()";
var author ="$('.avatar__name').text()";

中国证券网

1
2
3
4
5
6
7
8
9
10
11
12
13
var source_name = "中国证券网";
var domain = 'http://www.cnstock.com/';
var myEncoding = "GBK";
var seedURL = 'http://www.cnstock.com/';

var seedURL_format = "$('a')";//a-href
var regExp =/news,[a-zA-Z]{4}-\d{6}-\d+[.]/;//获取a href的正则表达式

var title_format = "$('.title').text()";
var pubtime = "$('.timer').text()";
var article_source = "$('.source').text()";
var content_format ="$('.content').text()";
var author ="$('.author').text()";
  • 这里同样注意,中国证券网也是GBK编码的

中财网

1
2
3
4
5
6
7
8
9
10
11
12
13
var source_name = "中财网";
var domain = 'http://www.cfi.net.cn/';
var myEncoding = "utf-8";
var seedURL = 'http://www.cfi.net.cn/';

var seedURL_format = "$('a')";//a-href
var regExp =/[a-z]\d+[.]/;//获取a href的正则表达式

var title_format = "$('h1').text()";
var pubtime = "$('.time').text()";
var article_source = "$('.source data-source').text()";
var content_format ="$('.Body').text()";
var author ="$('.res-edit').text()";

凤凰财经

1
2
3
4
5
6
7
8
9
10
11
12
13
var source_name = "凤凰财经";
var domain = 'http://finance.ifeng.com/';
var myEncoding = "utf-8";
var seedURL = 'http://finance.ifeng.com/';

var seedURL_format = "$('a')";//a-href
var regExp =/\/.\/[1-9a-zA-Z]{10}/;//获取a href的正则表达式

var title_format = "$('.topic-3bY8Hw-9').text()";
var pubtime = "$('.time-hm3v7ddj').text()";
var article_source = "$('.source-2pXi2vGI').text()";
var content_format ="$('.text-3zQ3cZD4').text()";
var author ="$('#editor_baidu').text()";

新浪财经

1
2
3
4
5
6
7
8
9
10
11
12
13
var source_name = "新浪财经";
var domain = 'https://finance.sina.com.cn/';
var myEncoding = "utf-8";
var seedURL = 'https://finance.sina.com.cn/';

var seedURL_format = "$('a')";//a-href
var regExp =/\/.+\/\d{4}-\d{2}-\d{2}\/.+[.]shtml/;//获取a href的正则表达式

var title_format = "$('.main-title').text()";
var pubtime = "$('.date').text()";
var article_source = "$('.source ent-source').text()";
var content_format ="$('#artibody').text()";
var author ="$('.article-editor').text()";

财经网

1
2
3
4
5
6
7
8
9
10
11
12
13
var source_name = "财经网";
var domain = 'http://www.caijing.com.cn/';
var myEncoding = "utf-8";
var seedURL = 'http://www.caijing.com.cn/';

var seedURL_format = "$('a')";//a-href
var regExp =/\/\d+\/\d+[.]shtml/;//获取a href的正则表达式

var title_format = "$('#cont_title').text()";
var pubtime = "$('#pubtime_baidu').text()";
var article_source = "$('#source_baidu').text()";
var content_format ="$('#the_content').text()";
var author ="$('#editor_baidu').text()";

金融界

1
2
3
4
5
6
7
8
9
10
11
12
13
var source_name = "金融界";
var domain = 'http://www.jrj.com.cn/';
var myEncoding = "GBK";
var seedURL = 'http://www.jrj.com.cn/';

var seedURL_format = "$('a')";//a-href
var regExp =/\/\d{4}\/\d{2}\/\d+[.]/;//获取a href的正则表达式

var title_format = "$('h1').text()";
var pubtime = "$('.inftop').text()";
var article_source = "$('h1').text()";
var content_format ="$('.texttit_m1').text()";
var author ="$('h1').text()";
  • 注意,金融界也是GBK编码的网站

这些网站的爬虫,我也都有存储至MySQL

  • 这里牵扯到一些复杂的分类问题

  • 一开始我想把所有文件分开来放在不同databse下的不同table

  • 但是后来我觉得切换不是很方便,所以直接把所有table放在同一个crawl 数据库下
  • 最后,因为爬取了很多金融网站,而且为了给最后的express框架做一些内容上的支撑,所以我把所有的财经类网站放到了一张名为经济新闻的表中,这时候我们可以看到一张巨大的表格
  • 示例
-------------本文结束,感谢您的阅读-------------