财通国际人才网佛山区域爬虫

一、选题背景:通过爬虫,可以更清楚地了解各公司的招聘要求的真实情况,从而在最短的时间内发现问题,找到自己最适合的岗位,从而节约了很多时间。
二、主题式网络爬虫设计方案(15分)
1.主题式网络爬虫名称
  链家招聘网站佛山区域爬虫
2.主题式网络爬虫爬取的内容与数据特征分析
    爬取链家上面发布的职位信息,分析佛山各区域,不同岗位的学历要求
3.主题式网络爬虫设计方案概述(包括实现思路与技术难点)
   爬取链家当中佛山各区域不同岗位所需各种学历人才数的通过分析其网页特征来使用python代码切换不同的区域页面再通过提取出不同城市不同岗位所需各种学历人才数进行绘制柱状图。
   技术难点:链家的内容较多,在分析其网页结构可能会比普通的求职网站要来得复杂一些,并且注意识别其中一些广告内容。
三、主题页面的结构特征分析(15分)
1.主题页面的结构与特征分析:通过观察页面HTML源代码,可以发现每个职位名称的标题都位于'div',class="jobsList"标签的子标签中,而学历要求则位于'span', class_="line_list"标签的子标签中,通过标签的关系进行遍历得到需要的内容
目标网址:https://www.job001.cn/jobs?keyType=0

 

 

 

 

 

 


 

 3.节点(标签)查找方法与遍历方法

#获取总的div数据量
        divs = html.xpath('//div[@id="infolists"]/div[position()>1]')
        for div in divs:
            #提取数据
            job_dic ={}
            #工作信息
            job_dic['job'] = div.xpath('.//dt[@class="mouseListen"]/div[1]/a/text()')[0].strip()
            #地区信息
            job_dic['area'] = div.xpath('.//span[@class="cityConJobsWork"]/text()')[0].strip()

四、网络爬虫程序设计(60分)
爬虫程序主体要包括以下各部分,要附源代码及较详细注释,并在每部分程序后面提供输出结果的截图。

1.数据爬取与采集

 

def get_page_and_parser():
    #35
    #统计数据的类型总量
    data_num = 1
    #创建pandas数据集
    data = pd.DataFrame()
    #设置访问的最大页数
    for page in range(1,35):
        url = "https://www.job001.cn/jobs?keyType=0&" \
              "jobType=%E8%81%8C%E4%BD%8D%E7%B1%BB%E5%9E%8B" \
              "&industryname=%E8%A1%8C%E4%B8%9A%E7%B1%BB%E5%9E%8B" \
              f"&workId=25.296&workPlace=" \
              f"%E4%BD%9B%E5%B1%B1%E5%B8%82&pageNo={str(page)}"
        print(url)
        #请求网页
        resp = requests.get(url,headers=headers)
        print(resp.text)

结果:

 

 2.对数据进行清洗与处理

job_dic ={}
            #工作信息
            job_dic['job'] = div.xpath('.//dt[@class="mouseListen"]/div[1]/a/text()')[0].strip()
            #地区信息
            job_dic['area'] = div.xpath('.//span[@class="cityConJobsWork"]/text()')[0].strip()
            #刷新时间信息
            job_dic['flash_time'] = div.xpath('.//dt[@class="mouseListen"]/div[1]/span[2]/text()')[0].strip()
            #薪水信息
            salary = div.xpath('.//span[@class="salaryList"]//text()')[0].strip()
            #对提取的薪水信息进行处理
            salary = salary.split("-")[0]

            if salary.startswith("("):
                salary = salary.split(")")[-1]
                if salary == "":
                    salary =0
            job_dic['salary'] = float(salary)
            #公司信息
            company = div.xpath('.//div[@class="jobRight"]/dt/a/text()')[0]

            #招聘公司信息
            job_dic['company'] = company.strip()
            #职位类型
            job_dic['type'] = div.xpath(".//dd[@class='company-info']/span[1]/text()")[0]

            #输出提取的信息
            print(f"data num:{str(data_num)}--", job_dic['job'],
                  job_dic['area'], job_dic['salary'],
                  job_dic['flash_time'], job_dic['company'],job_dic['type'])

 

2.2对工作区域数据处理

def draw_area(data):
    #对area数据处理
    data = data.groupby(['area'])['salary']\
        .agg(['mean','count']).reset_index()
    data = sorted([(row['area'],round(row['mean'],1))
                   for _,row in data.iterrows()],
                  key=lambda x:x[1])
    print(data)

 

 

 2.3对工作数据进行处理

def draw_job(data):
    # 对job数据进行分类处理
    data = data.groupby(['salary'])['area'].\
        count().reset_index()
    data = sorted([(row['salary'], row['area'])
                  for _, row in data.iterrows()],
                  key=lambda x: x[1], reverse=True)
    print(data)

            #存入pandas
            if data.empty:
                data = pd.DataFrame(job_dic, index=[0])

            else:
                data = data.append(job_dic, ignore_index=True)
            data_num += 1

        #设置延时,防止被墙
        time.sleep(random.randint(1,3))
        if page%5 ==0:
            time.sleep(10)

    #把所有数据写入excl中
    data.head()
    print(data)
    data.to_excel("foshan.xlsx")

 

 

 

 

3.数据分析与可视化

bar = (
        Funnel()
            .add(
            "企业性质和平均薪资排行",
            data,
            sort_="ascending",
            label_opts=opts.LabelOpts(position="inside"),
        )
            .set_global_opts(title_opts=
            opts.TitleOpts(title="佛山招聘企业性质和平均薪资占比"))
    )
    bar.render("templates/佛山招聘企业性质和平均薪资排行.html")

 

 

 

pie = (
        Pie(init_opts=opts.InitOpts(theme='dark'))
           .add('', data,
                radius=["30%", "75%"],
                rosetype="radius")
           .set_global_opts(title_opts=opts.TitleOpts(title="佛山各个区域招聘薪资范围的占比"),
                            legend_opts=opts.LegendOpts(is_show=False), )
           .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {d}%"))
           )
    pie.render("templates/佛山招聘薪资范围的占比.html")

 

 4.数据分析与可视化(例如:数据柱形图、直方图、散点图、盒图、分布图)

bar = (
        Bar(init_opts=opts.InitOpts(theme='dark'))

           .add_xaxis([x[0] for x in data])
           .add_yaxis('佛山各区域招聘均价', [x[1] for x in data])

           .set_global_opts(
        title_opts=opts.TitleOpts(title="佛山各区域招聘均价排行"),
        legend_opts=opts.LegendOpts(is_show=False),
        tooltip_opts=opts.TooltipOpts(formatter='{b}:{c}千元'))
           .reversal_axis()
           )
    bar.render("templates/佛山各区域招聘均价排行.html")

 

  完整代码

  1 import requests
  2 from lxml import etree
  3 import time
  4 import random
  5 import pandas as pd
  6 from flask import Flask,render_template
  7 from jinja2 import Markup
  8 from pyecharts import options as opts
  9 from pyecharts.charts import Bar, Pie,Funnel
 10 
 11 
 12 
 13 #添加请求头,防止被墙
 14 headers = {
 15     "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 "
 16                   "(KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36"
 17 }
 18 
 19 #定义需要解析的信息
 20 def get_page_and_parser():
 21     #35
 22     #统计数据的类型总量
 23     data_num = 1
 24     #创建pandas数据集
 25     data = pd.DataFrame()
 26     #设置访问的最大页数
 27     for page in range(1,35):
 28         url = "https://www.job001.cn/jobs?keyType=0&" \
 29               "jobType=%E8%81%8C%E4%BD%8D%E7%B1%BB%E5%9E%8B" \
 30               "&industryname=%E8%A1%8C%E4%B8%9A%E7%B1%BB%E5%9E%8B" \
 31               f"&workId=25.296&workPlace=" \
 32               f"%E4%BD%9B%E5%B1%B1%E5%B8%82&pageNo={str(page)}"
 33         print(url)
 34         #请求网页
 35         resp = requests.get(url,headers=headers)
 36         # print(resp.text)
 37         #解析网页
 38         html = etree.HTML(resp.text)
 39         #获取总的div数据量
 40         divs = html.xpath('//div[@id="infolists"]/div[position()>1]')
 41         for div in divs:
 42             #提取数据
 43             job_dic ={}
 44             #工作信息
 45             job_dic['job'] = div.xpath('.//dt[@class="mouseListen"]/div[1]/a/text()')[0].strip()
 46             #地区信息
 47             job_dic['area'] = div.xpath('.//span[@class="cityConJobsWork"]/text()')[0].strip()
 48             #刷新时间信息
 49             job_dic['flash_time'] = div.xpath('.//dt[@class="mouseListen"]/div[1]/span[2]/text()')[0].strip()
 50             #薪水信息
 51             salary = div.xpath('.//span[@class="salaryList"]//text()')[0].strip()
 52             #对提取的薪水信息进行处理
 53             salary = salary.split("-")[0]
 54 
 55             if salary.startswith("("):
 56                 salary = salary.split(")")[-1]
 57                 if salary == "":
 58                     salary =0
 59             job_dic['salary'] = float(salary)
 60             #公司信息
 61             company = div.xpath('.//div[@class="jobRight"]/dl/dt/a/text()')[0]
 62 
 63             #招聘公司信息
 64             job_dic['company'] = company.strip()
 65             #职位类型
 66             job_dic['type'] = div.xpath(".//dd[@class='company-info']/span[1]/text()")[0]
 67 
 68 
 69             #输出提取的信息
 70             print(f"data num:{str(data_num)}--", job_dic['job'],
 71                   job_dic['area'], job_dic['salary'],
 72                   job_dic['flash_time'], job_dic['company'],job_dic['type'])
 73 
 74             #存入pandas
 75             if data.empty:
 76                 data = pd.DataFrame(job_dic, index=[0])
 77 
 78             else:
 79                 data = data.append(job_dic, ignore_index=True)
 80             data_num += 1
 81 
 82         #设置延时,防止被墙
 83         time.sleep(random.randint(1,3))
 84         if page%5 ==0:
 85             time.sleep(10)
 86 
 87     #把所有数据写入excl中
 88     data.head()
 89     print(data)
 90     data.to_excel("foshan.xlsx")
 91 
 92 
 93 #佛山各区域招聘的均价
 94 def draw_area(data):
 95     #对area数据处理
 96     data = data.groupby(['area'])['salary']\
 97         .agg(['mean','count']).reset_index()
 98     data = sorted([(row['area'],round(row['mean'],1))
 99                    for _,row in data.iterrows()],
100                   key=lambda x:x[1])
101     # #图像绘制
102     #[('三水区/西南', 3.0), ('南海区/官窑', 3.0), ('南海区/南海周边', 3.4), ('广东', 3.4),
103     print(data)
104     bar = (
105         Bar(init_opts=opts.InitOpts(theme='dark'))
106 
107            .add_xaxis([x[0] for x in data])
108            .add_yaxis('佛山各区域招聘均价', [x[1] for x in data])
109 
110            .set_global_opts(
111         title_opts=opts.TitleOpts(title="佛山各区域招聘均价排行"),
112         legend_opts=opts.LegendOpts(is_show=False),
113         tooltip_opts=opts.TooltipOpts(formatter='{b}:{c}千元'))
114            .reversal_axis()
115            )
116     bar.render("templates/佛山各区域招聘均价排行.html")
117     return bar
118 
119 #佛山招聘企业性质和平均薪资
120 def draw_type(data):
121     #对type数据进行分类处理
122     data = data.groupby(['type'])['salary'].\
123         agg(['mean', 'count']).reset_index()
124     data = sorted([(row['type'], round(row['mean'], 1))
125                    for _, row in data.iterrows()], key=lambda x: x[1])
126     print(data)
127     bar = (
128         Funnel()
129             .add(
130             "企业性质和平均薪资排行",
131             data,
132             sort_="ascending",
133             label_opts=opts.LabelOpts(position="inside"),
134         )
135             .set_global_opts(title_opts=
136             opts.TitleOpts(title="佛山招聘企业性质和平均薪资占比"))
137     )
138     bar.render("templates/佛山招聘企业性质和平均薪资排行.html")
139     return bar
140 
141 #佛山各个区域招聘薪资范围的占比
142 def draw_job(data):
143     # 对job数据进行分类处理
144     data = data.groupby(['salary'])['area'].\
145         count().reset_index()
146     data = sorted([(row['salary'], row['area'])
147                   for _, row in data.iterrows()],
148                   key=lambda x: x[1], reverse=True)
149 
150     pie = (
151         Pie(init_opts=opts.InitOpts(theme='dark'))
152            .add('', data,
153                 radius=["30%", "75%"],
154                 rosetype="radius")
155            .set_global_opts(title_opts=opts.TitleOpts(title="佛山各个区域招聘薪资范围的占比"),
156                             legend_opts=opts.LegendOpts(is_show=False), )
157            .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {d}%"))
158            )
159     pie.render("templates/佛山招聘薪资范围的占比.html")
160     return pie
161     
162 #创建flask app
163 app = Flask(__name__,static_folder="templates")
164 
165 #创建pandas数据集
166 df = pd.read_excel("foshan.xlsx",engine="openpyxl")
167 
168 #对数据进行重复值删除,None值删除
169 data = df.drop_duplicates()
170 data = data.dropna()
171 
172 #设置主页路由
173 @app.route("/")
174 def index():
175     return render_template("index.html")
176 
177 #地区的路由
178 @app.route("/area")
179 def area():
180     #生成area图例
181     area = draw_area(data)
182     # 生成area图例
183     return Markup(area.render_embed())
184 
185 #类型的路由
186 @app.route("/type")
187 def salary():
188     # 生成area图例
189     type = draw_type(data)
190     # 渲染area图例
191     return Markup(type.render_embed())
192 
193 #工作的路由
194 @app.route("/job")
195 def job():
196     # 生成job图例
197     job = draw_job(data)
198     # 生渲染job图例
199     return Markup(job.render_embed())
200 
201 #主要调用模块
202 if __name__ == '__main__':
203     #生成数据
204     get_page_and_parser()
205     #开启flask服务器展示数据
206     app.run(host="0.0.0.0",port=8080)
207 
208 
209     

 

1.经过对主题数据的分析与可视化,可以得到哪些结论?

  1.顺德区的薪资占各区域的前三名,其中乐从远高于其他区。

  2.建筑建材的薪资最高,外商独资其次,事业单位的薪资最低。

2.在完成此设计过程中,得到哪些收获?以及要改进的建议?

完成此项作业才发现自己还有如此多的不懂,仍然需要不断学习,刻苦专研。在完成作业的途中,通过查阅各种资料,提升了我对这门学科浓厚的兴趣。我觉得这次爬虫的内容还挺有意思的,也让我学到了很多书本以外的知识,一步一步自己探索出来,遇到不懂的问题及时问同学答疑解惑。这一次任务按照老师的要求一步一步来实现,虽然有一些没有完全实现出来,还存在在很多问题,但是发现问题多了也就能及时查缺补漏,让我们对Python这门语言有了更深的理解,也让我增加了更多的兴趣对于这个课程,能够让自己能更好地进步。今后一定会更加努力的。

 

 

posted @ 2021-12-30 13:04  哦嗯啊  阅读(134)  评论(0编辑  收藏  举报