├── Analysis
├── Analysis.xlsx
└── IntershipAnalysis.pdf
├── README.md
├── codes
├── cityPro.py
├── count_citys.txt
├── data.txt
├── fenci.py
├── shixiseng.py
└── wordFreq.py
└── datas
└── sxseng.xls
/Analysis/Analysis.xlsx:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunjunee/internshipAnalysis/92b95816db56542ec36635507a2ba660bdc56ab2/Analysis/Analysis.xlsx
--------------------------------------------------------------------------------
/Analysis/IntershipAnalysis.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunjunee/internshipAnalysis/92b95816db56542ec36635507a2ba660bdc56ab2/Analysis/IntershipAnalysis.pdf
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 这是一个爬取**实习僧**网站信息 [截止2017年8月8日] 的爬虫,并对爬取的结果做了一些简单的处理。
2 |
3 | 使用的工具是python,用到了requests和Beautifulsoup来进行网页爬取,jieba进行分词处理。
4 |
5 | 一些总结放在: https://sunjunee.github.io/2017/09/25/intership-analysis/
6 |
7 | ## 爬虫
8 | 这里想爬的是实习僧网站上,所有互联网相关的实习招聘信息。打开网站可以看到目录:
9 |
10 | 
11 |
12 | 点开一个目录,其跳转的链接为:
13 | https://www.shixiseng.com/interns?k=关键词&p=页码
14 |
15 | 于是可以通过上述链接,来获取所有互联网相关实习信息的列表,我在这里只取了该实习的链接,因为仔细观察可以发现,网页上的文字爬取下来都是乱码的,这可能是使用了特殊的字体和编码的原因。
16 |
17 | 不得不说,这一招用来反爬虫还是很有效的。打开每个实习地详情页,也都存在各种乱码。
18 |
19 | 
20 |
21 | 但是,如果是乱码就完全不能分析了啊。然而,毕竟是,道高一尺魔高一丈,电脑端不行,我们转战手机网页端。
22 |
23 | 然后,就欣喜地发现,wwap网站有一个专门用来传递信息的API,真是得来全不费工夫啊,直接用API,解析的功夫都省了:
24 |
25 | 
26 |
27 | 其用法是http://wap.shixiseng.com/app/intern/info?uuid=实习id
28 | 前面已经通过检索,爬到了所有互联网相关的实习链接,链接里面,就包含实习id,于是,数据就很方便地爬下来了~
29 |
30 | ```python
31 | import requests;
32 | from bs4 import BeautifulSoup;
33 |
34 | source = 'http://www.shixiseng.com/interns?k=前端&p='; pages = 37;
35 | source2 = 'http://wap.shixiseng.com/app/intern/info?uuid=';
36 | data = [];
37 | for i in range(1, pages+1):
38 | try:
39 | r = requests.get(source + str(i)); r.encoding = 'utf-8';
40 | soup = BeautifulSoup(r.text, 'html.parser')
41 | li = soup.find_all('div', attrs={'class':'list'});
42 | #解析网页
43 | for j in range(len(li)):
44 | s = li[j]; cag = (s.find('div', attrs = {'class':'part'}).text).split(' - ')[1];
45 | #链接:
46 | link = s.find('div', attrs = {'class':'names cutom_font'}).find('a').attrs['href']
47 | link = link.split('/')[2];
48 | r2 = requests.get(source2 + link); r2.encoding = 'utf-8';
49 | infos = eval(r2.text);
50 | data.append(infos);
51 | except:
52 | print('Error!');
53 | ```
54 |
55 | ## 分词
56 |
57 | 这里做分词的目的,主要是因为爬取下来的结构化信息确实不多,于是对职位描述这个字段进行分词,用到的工具是jieba。
58 |
59 | 使用的方法也很简单,分词后,使用对结果进行分割,存储到了mysql中。
60 |
61 | ```python
62 | import jieba
63 | from bs4 import BeautifulSoup;
64 |
65 | datas = {};
66 | for i in range(len(a)):
67 | s = BeautifulSoup(a[i][1], 'html.parser').text;
68 | datas[i+1] = s.replace('\xa0','');
69 |
70 | #分词
71 | seged = {};
72 | for key in datas.keys():
73 | view_bar(key, len(datas))
74 | seg = jieba.cut(datas[key], cut_all=False)
75 | seg = [s for s in seg];
76 | seged[key] = seg;
77 | seg = ''.join(seg);
78 |
79 | ```
80 |
81 | ## 后续分析
82 | 使用mysql进行查询、Excel简单地可视化。
83 |
84 |
--------------------------------------------------------------------------------
/codes/cityPro.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | @ Author: Jun Sun {Python3}
4 | @ E-mail: sunjunee@qq.com
5 | @ Create: 2017-08-13 10:10
6 |
7 | Descript:
8 | """
9 |
10 | f = open('data.txt', 'r', encoding = 'utf-8');
11 |
12 | datas = [];
13 | while(True):
14 | line = f.readline();
15 | if(line):
16 | line = line.split('\t'); line[-1] = line[-1][0:-1];
17 | datas.append([line[0],line[1:]]);
18 | else:
19 | f.close(); break;
20 |
21 | counts = {};
22 | for i in range(len(datas)):
23 | for j in range(len(datas[i][1])):
24 | if datas[i][1][j] != '':
25 | if(datas[i][1][j] not in counts.keys()):
26 | counts[datas[i][1][j]] = eval(datas[i][0]);
27 | else:
28 | counts[datas[i][1][j]] += eval(datas[i][0]);
29 |
30 | f = open('count_citys.txt', 'w');
31 | for key in counts.keys():
32 | f.write(key + '\t' + str(counts[key]) + '\n');
33 | f.close();
--------------------------------------------------------------------------------
/codes/count_citys.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunjunee/internshipAnalysis/92b95816db56542ec36635507a2ba660bdc56ab2/codes/count_citys.txt
--------------------------------------------------------------------------------
/codes/data.txt:
--------------------------------------------------------------------------------
1 | 1 杭州
2 | 1 武汉
3 | 1 苏州 上海 上海
4 | 1022 上海
5 | 3 上海 北京
6 | 2 上海 南京
7 | 4 上海 大连
8 | 2 上海 大连 广州
9 | 2 上海 天津
10 | 1 上海 杭州
11 | 1 上海 深圳
12 | 11 上海 苏州
13 | 1 上海 西安
14 | 1 上海 青岛
15 | 1 上海
16 | 5 东莞
17 | 2 乌鲁木齐
18 | 7 佛山
19 | 1 佛山 清远 肇庆 韶关 江门 揭阳
20 | 11 全国
21 | 3 兰州
22 | 1 兴义
23 | 1928 北京
24 | 6 北京 上海
25 | 1 北京 上海
26 | 1 北京 上海 广州
27 | 1 北京 上海 深圳
28 | 3 北京 上海 西安
29 | 2 北京 南京 成都 上海 杭州 郑州 济南 厦门 长沙 广州
30 | 1 北京 广州 上海 南京 温州
31 | 1 北京 成都 上海 杭州
32 | 1 北京 昆明 天津 太原 呼和浩特
33 | 1 北京 深圳
34 | 4 北京 珠海
35 | 2 北京 石家庄
36 | 2 北京 西安
37 | 1 北京 长沙
38 | 1 北京 青岛 哈尔滨 石家庄
39 | 1 北京 香港
40 | 3 北京市
41 | 132 南京
42 | 1 南京 佛山 深圳
43 | 2 南京 北京
44 | 1 南京 苏州
45 | 10 南宁
46 | 8 南昌
47 | 1 南通
48 | 26 厦门
49 | 15 合肥
50 | 1 呼和浩特
51 | 5 哈尔滨
52 | 103 大连
53 | 4 大连 沈阳
54 | 29 天津
55 | 2 宁夏
56 | 8 宁波
57 | 1 广东
58 | 418 广州
59 | 2 广州 佛山
60 | 2 广州 佛山 长沙 海口
61 | 1 广州 北京 上海
62 | 1 广州 成都
63 | 2 广州 杭州
64 | 1 广州 深圳
65 | 3 广州 珠海
66 | 1 廊坊
67 | 4 徐州
68 | 1 惠州
69 | 305 成都
70 | 2 成都 宁波
71 | 1 成都 重庆
72 | 2 拉萨
73 | 1 攀枝花
74 | 18 无锡
75 | 1 日客则 林芝
76 | 1 日本
77 | 1 昆山
78 | 10 昆明
79 | 265 杭州
80 | 2 杭州 上海
81 | 1 杭州 南京
82 | 1 杭州 无锡
83 | 1 柳州
84 | 104 武汉
85 | 1 武汉 西安
86 | 1 汕尾 深圳
87 | 1 江门
88 | 16 沈阳
89 | 1 泉州
90 | 12 济南
91 | 1 济南 郑州
92 | 5 海口
93 | 1 海口 北京
94 | 227 深圳
95 | 1 深圳 合肥
96 | 1 深圳 广州
97 | 2 深圳 香港
98 | 17 珠海
99 | 1 盐城
100 | 2 石家庄
101 | 17 福州
102 | 1 福建
103 | 39 苏州
104 | 1 西宁
105 | 45 西安
106 | 5 贵阳
107 | 15 郑州
108 | 45 重庆
109 | 1 重庆 贵阳
110 | 1 银川
111 | 4 长春
112 | 30 长沙
113 | 19 青岛
114 | 1 青岛 上海
115 | 1 香港 深圳
116 |
--------------------------------------------------------------------------------
/codes/fenci.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | @ Author: Jun Sun {Python3}
4 | @ E-mail: sunjunee@qq.com
5 | @ Create: 2017-08-09 19:51
6 |
7 | Descript:
8 | """
9 | import pymysql;
10 | import jieba
11 | from bs4 import BeautifulSoup;
12 | import math;
13 | import sys;
14 |
15 | def view_bar(num, total):
16 | rate = num / total
17 | rate_num = int(rate * 40)
18 | rate_nums = math.ceil(rate * 100);
19 | r = '\r[%s%s]%d%%\t%d/%d\t' % (">"*rate_num, " "*(40-rate_num), rate_nums, num, total,)
20 | sys.stdout.write(r)
21 | sys.stdout.flush()
22 |
23 | db = pymysql.connect("localhost", "root", "Admin123456!", "test", charset="utf8");
24 | cursor = db.cursor();
25 | cursor.execute("SELECT id, info FROM sxseng")
26 | a = cursor.fetchall();
27 |
28 | datas = {};
29 | for i in range(len(a)):
30 | s = BeautifulSoup(a[i][1], 'html.parser').text;
31 | datas[i+1] = s.replace('\xa0','');
32 |
33 | #分词、存储到mysql
34 | seged = {};
35 | for key in datas.keys():
36 | view_bar(key, len(datas))
37 | seg = jieba.cut(datas[key], cut_all=False)
38 | seg = [s for s in seg];
39 | seged[key] = seg;
40 | seg = ''.join(seg);
41 |
42 | sql = "UPDATE sxseng set info_cut = '%s' where id = '%d'" % (seg, key);
43 | try:
44 | cursor.execute(sql)
45 | db.commit()
46 | except:
47 | print('Error!');
48 | # db.rollback()
49 |
50 | db.close();
51 |
--------------------------------------------------------------------------------
/codes/shixiseng.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | @ Author: Jun Sun {Python3}
4 | @ E-mail: sunjunee@qq.com
5 | @ Create: 2017-08-07 19:52
6 |
7 | Descript: 从实习僧网站爬取数据
8 | """
9 |
10 | import requests;
11 | from bs4 import BeautifulSoup;
12 | import sys;
13 | import math;
14 | import pymysql;
15 |
16 | def view_bar(num, total):
17 | rate = num / total
18 | rate_num = int(rate * 40)
19 | rate_nums = math.ceil(rate * 100);
20 | r = '\r[%s%s]%d%%\t%d/%d\t' % (">"*rate_num, " "*(40-rate_num), rate_nums, num, total,)
21 | sys.stdout.write(r)
22 | sys.stdout.flush()
23 |
24 | source = 'http://www.shixiseng.com/interns?k=前端&p=';
25 | pages = 37;
26 | source2 = 'http://wap.shixiseng.com/app/intern/info?uuid=';
27 |
28 | data = [];
29 |
30 | for i in range(1, pages+1):
31 | view_bar(i, pages);
32 | try:
33 | r = requests.get(source + str(i));
34 | r.encoding = 'utf-8';
35 |
36 | soup = BeautifulSoup(r.text, 'html.parser')
37 | li = soup.find_all('div', attrs={'class':'list'});
38 |
39 | #解析网页
40 |
41 | for j in range(len(li)):
42 | s = li[j];
43 |
44 | cag = (s.find('div', attrs = {'class':'part'}).text).split(' - ')[1];
45 |
46 | #链接:
47 | link = s.find('div', attrs = {'class':'names cutom_font'}).find('a').attrs['href']
48 | link = link.split('/')[2];
49 |
50 | r2 = requests.get(source2 + link);
51 | r2.encoding = 'utf-8';
52 |
53 | infos = eval(r2.text);
54 |
55 | data.append(infos);
56 | except:
57 | print('Error!');
58 |
59 | print('\n');
60 | #存入mysql
61 | db = pymysql.connect("localhost", "root", "Admin123456!", "test", charset="utf8");
62 | cursor = db.cursor();
63 | #cursor.execute("DROP TABLE IF EXISTS sxseng")
64 | #
65 | #sql = """CREATE TABLE sxseng (
66 | # cag CHAR(255),
67 | # iname CHAR(255),
68 | # industry CHAR(255),
69 | # cname CHAR(255),
70 | # city CHAR(255),
71 | # address CHAR(255),
72 | # attraction CHAR(255),
73 | # chance CHAR(255),
74 | # degree CHAR(255),
75 | # maxsal CHAR(255),
76 | # minsal CHAR(255),
77 | # month CHAR(255),
78 | # scale CHAR(255),
79 | # info TEXT(2047),
80 | # url CHAR(255))"""
81 | #
82 | #cursor.execute(sql);
83 |
84 | i = 0;
85 | #Load to mysql:
86 | for d in data:
87 | i+=1;
88 | view_bar(i, len(data));
89 | sql = "INSERT INTO sxseng(cag, iname, industry, cname, city, address, attraction, chance, degree, maxsal, minsal, month, scale, info, url) \
90 | VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s')" % \
91 | (cag, d['msg']['iname'], d['msg']['industry'], d['msg']['cname'], d['msg']['city'], d['msg']['address'], d['msg']['attraction'], d['msg']['chance'],\
92 | d['msg']['degree'], d['msg']['maxsal'], d['msg']['minsal'], d['msg']['month'], d['msg']['scale'], d['msg']['info'], d['msg']['url']);
93 | try:
94 | cursor.execute(sql)
95 | db.commit()
96 | except:
97 | db.rollback()
98 | db.close();
99 |
--------------------------------------------------------------------------------
/codes/wordFreq.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 | """
3 | @ Author: Jun Sun {Python3}
4 | @ E-mail: sunjunee@qq.com
5 | @ Create: 2017-08-09 20:54
6 |
7 | Descript: 统计词频
8 | """
9 |
10 | import pymysql;
11 | import sys;
12 | import math;
13 |
14 | def view_bar(num, total):
15 | rate = num / total
16 | rate_num = int(rate * 40)
17 | rate_nums = math.ceil(rate * 100);
18 | r = '\r[%s%s]%d%%\t%d/%d\t' % (">"*rate_num, " "*(40-rate_num), rate_nums, num, total,)
19 | sys.stdout.write(r)
20 | sys.stdout.flush()
21 |
22 | db = pymysql.connect("localhost", "root", "Admin123456!", "test", charset="utf8");
23 | cursor = db.cursor();
24 | cursor.execute("SELECT id, info_cut FROM sxseng")
25 | datas = cursor.fetchall();
26 | db.close();
27 |
28 | wordBook = []; count = [];
29 | for i in range(len(datas)):
30 | data = datas[i][1];
31 | data = data.split('');
32 | view_bar(i, len(datas));
33 | for word in data:
34 | if word not in wordBook:
35 | wordBook.append(word);
36 | count.append(1);
37 | else:
38 | count[wordBook.index(word)] += 1;
39 |
40 | #存储到mysql:
41 | db = pymysql.connect("localhost", "root", "Admin123456!", "test", charset="utf8");
42 | cursor = db.cursor();
43 | cursor.execute("DROP TABLE IF EXISTS wordFreq")
44 |
45 | sql = """CREATE TABLE wordFreq (
46 | word CHAR(255),
47 | freq int)"""
48 |
49 | cursor.execute(sql);
50 |
51 | #Load to mysql:
52 | for i in range(len(wordBook)):
53 | view_bar(i, len(wordBook));
54 | sql = "INSERT INTO wordFreq(word, freq) \
55 | VALUES ('%s', '%d')" % \
56 | (wordBook[i], count[i]);
57 | try:
58 | cursor.execute(sql)
59 | db.commit()
60 | except:
61 | db.rollback()
62 | db.close();
63 |
--------------------------------------------------------------------------------
/datas/sxseng.xls:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/sunjunee/internshipAnalysis/92b95816db56542ec36635507a2ba660bdc56ab2/datas/sxseng.xls
--------------------------------------------------------------------------------