关于简单的爬虫以及简单的Flask交互

一、关于 Ajax简介

AJAX = Asynchronous JavaScript and XML(异步 JavaScript 和 XML)。AJAX 是一种创建快速动态网页的技术。通过在后台与服务器交换少量数据,AJAX 允许网页进行异步更新。这意味着,在不重新加载整个网页的情况下,对网页某些部分进行更新。典型的网页(不使用 AJAX),如果内容发生变化,就必须重载整个页面。使用 AJAX 的典型案例包括:谷歌地图、腾讯微博、优酷视频等等。

在这里插入图片描述

二、页面的分析

1.进入到腾讯招聘的页面

在这里插入图片描述

2.搜索我们所要的岗位

在这里插入图片描述

3.搜索的到相关的招聘信息

在这里插入图片描述

但是通过有健查看源代码却找不到招聘信息

在这里插入图片描述

4.通过分析可以得到真正的url

在这里插入图片描述

三、数据的提取

1.request,urllib.parse库

Request对象的作用是与客户端交互,收集客户端的Form、Cookies、超链接,或者收集服务器端的环境变量。request对象是从客户端向服务器发出请求,包括用户提交的信息以及客户端的一些信息。客户端可通过HTML表单或在网页地址后面提供参数的方法提交数据,然后服务器通过request对象的相关方法来获取这些数据。request的各种方法主要用来处理客户端浏览器提交的请求中的各项参数和选项

在这里插入图片描述


urllib主要提供了一些对url进行操作的功能

urllib是python内置的爬虫库,它包含4个模块:

  • request: 基础的 HTTP 请求模块。
  • error: 异常处理模块。
  • parse: 用于解析 URL 的模块。
  • parse.unquote:用于将url编码格式转换为中文
  • parse.quote:将中文转换为url编码
  • robotparser: 识别网站中 robots.txt 文件
import request
import urllib.parse
2.创建构建函数,将url 以及 掩盖爬虫制造伪信息的headers给补上
def __init__(self):
    self.url = "https://careers.tencent.com/tencentcareer/api/post/Query"    # 我们在网页上抓取到 url
    self.headers = {
        "user-agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36",
        "referer":"https://careers.tencent.com/search.html?keyword=%E8%AE%A1%E7%AE%97%E6%9C%BA"
    }
一些额外参数给补上

查看时间戳的地址:http://tool.chinaz.com/tools/unixtime.aspx

通过乘以1000倍并且四舍五入的方式达到跟网页一样的参数

在这里插入图片描述


def massgaes(self):

    parse ={
        "timestamp":str(round(time.time()*1000)),  # 时间切分成秒分数
        "keyword":self.position,    # 职位的名称
        "pageIndex":"1",  #页数
        "pageSize":"10",
        "language":"zh-cn",
        "area":"cn"
    }
    return parse
3.职位信息的获取(字典类型)

在这里插入图片描述

通过以健找值的方式提取我们想要的信息

for position_massage in position_massages:
    position = position_massage['RecruitPostName']
    position_name = re.sub(pattern=r'\(.*?)',string=position,repl="")   # 职位名称
    position_location = position_massage['LocationName']       #职位城市
    position_product = position_massage['ProductName']         # 职位所研发的产品
    position_category = position_massage['CategoryName']         # 职位的类型
    times = position_massage['LastUpdateTime']                # 职位上挂的时间
    time_model = "%Y年%m月%d日"
    time_touple = time.strptime(times,time_model)             # 将我们所提取的时间以这个模板提取出我们的时间数据
    year,month,days = time_touple[:3]
    position_time = datetime.date(year,month,days)           # 清洗后的职位时间
    position_country = position_massage['CountryName']        # 职位国家
    responsibility = position_massage['Responsibility']       # 职位要求
    position_responsibility = re.sub(pattern=r'\n',string=responsibility,repl=" ")   # 清洗后的职位要求
4.以字典的形式将数据储存到csv文件中去
position_data_dict = {
    "职位名称":position_name,
    "职位所在国家":position_country,
    "职位所在城市":position_location,
    "职位类型":position_category,
    "职位所研发的产品":position_product,
    "职位所发布的时间":position_time,
    "职位所发布的要求":position_responsibility
}
position_data.append(position_data_dict)   # 将信息添加到列表之中

四、数据的清洗(spark,pandas)

1.os创建当前目录
1.什么是os

https://www.runoob.com/python/os-file-methods.html

os模块提供了多数操作系统的功能接口函数。当os模块被导入后,它会自适应于不同的操作系统平台,根据不同的平台进行相应的操作,在python编程时,经常和文件、目录打交道,所以离不了os模块。python编程时,经常和文件、目录打交道,这是就离不了os模块,本节内容将对os模块提供的函数进行详细的解读

2.os的一些模块
  1. os.name——name顾名思义就是’名字’,这里的名字是指操作系统的名字,主要作用是判断目前正在使用的平台,并给出操作系统的名字,如Windows 返回 ‘nt’; Linux 返回’posix’。注意该命令不带括号。

  2. os.getcwd()——全称应该是’get current work directory’,获取当前工作的目录,如:返回结果为:‘C:\Program Files\Python36’。注意该命令带括号,除了第一个命令不带括号之外,以下命令基本都带括号。

  3. os.listdir(path)——列出path目录下所有的文件和目录名。

  4. os.remove(path)——删除path指定的文件,该参数不能省略。

  5. os.rmdir(path)——删除path指定的目录,该参数不能省略。

  6. os.mkdir(path)——创建path指定的目录,该参数不能省略。

注意:这样只能建立一层,要想递归建立可用:os.makedirs()

  1. os.path.isfile(path)——判断指定对象是否为文件。是返回True,否则False

  2. os.path.isdir(path)——判断指定对象是否为目录。是True,否则False

  3. os.path.exists(path)——检验指定的对象是否存在。是True,否则False.

  4. os.path.split(path)——返回路径的目录和文件名,即将目录和文件名分开,而不是一个整体。此处只是把前后两部分分开而已。就是找最后一个’/’。

  5. os.system(cmd)——执行shell命令。返回值是脚本的退出状态码,0代表成功,1代表不成功

  6. os.chdir(path)——'change dir’改变目录到指定目录

  7. os.path.getsize()——获得文件的大小,如果为目录,返回0

  8. os.path.abspath()——获得绝对路径。

  9. os.path.join(path, name)—连接目录和文件名,与os.path.split(path)相对。

16.os.path.basename(path)——返回文件名

  1. os.path.dirname(path)——返回文件路径

import os
import csv

# os.path.join(os.path.dirname(os.path.dirname(__file__)))  # os.path.dirname(__file__) 获得当前该级的目录 os.path.join 自己去拼接路劲
file = "E:/python练习合集/招聘文件"
name = "招聘.txt"
if not os.path.exists(file): #如果无该目录时
    os.mkdir(file)
    print("file创建成功")
if not os.path.isfile(name):
    name = file+r"/"+name
    f = open(name,"w",encoding="utf-8") #创建文件
    f.close()
    # os.mkdir(file+"/"+name)
    print("名字成家创建成功")

# with open(file,"a",encoding="utf-8") as o:
#     w = csv.writer(o)
#     w.writerow(a)


# 获取当前路劲
os.getcwd()
2.利用pandas存入csv文件

Pandas 是python的一个数据分析包,最初由AQR Capital Management于2008年4月开发,并于2009年底开源出来,目前由专注于Python数据包开发的PyData开发team继续开发和维护,属于PyData项目的一部分。

Pandas最初被作为金融数据分析工具而开发出来,因此,pandas为时间序列分析提供了很好的支持。 Pandas的名称来自于面板数据(panel data)和python数据分析(data analysis)。panel data是经济学中关于多维数据集的一个术语,在Pandas中也提供了panel的数据类型。

pandas 是字典形式,是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。Pandas 纳入了大量库和一些标准的数据模型,提供了高效地操作大型数据集所需的工具。pandas提供了大量能使我们快速便捷地处理数据的函数和方法。你很快就会发现,它是使Python成为强大而高效的数据分析环境的重要因素之一。

1.dataframe框架

属于一种高效的建立表格框架(https://blog.csdn.net/brucewong0516/article/details/81782312)

DataFrame.head([n]) #返回前n行数据 DataFrame.at #快速标签常量访问器 DataFrame.iat #快速整型常量访问器 DataFrame.loc #标签定位,使用名称 DataFrame.iloc #整型定位,使用数字 DataFrame.insert(loc, column, value) #在特殊地点loc[数字]插入column[列名]某列数据 DataFrame.iter() #Iterate over infor axis DataFrame.iteritems() #返回列名和序列的迭代器 DataFrame.iterrows() #返回索引和序列的迭代器 DataFrame.itertuples([index, name]) #Iterate over DataFrame rows as namedtuples, with index value as first element of the tuple. DataFrame.lookup(row_labels, col_labels) #Label-based “fancy indexing” function for DataFrame. DataFrame.pop(item) #返回删除的项目 DataFrame.tail([n]) #返回最后n行

2.pandas的写入方法
#3.pandas获取excel,csv文件
#3.1获取csv文件
file = r'E:\python练习合集\招聘文件\腾讯招聘文件.csv'

df = pd.read_csv(file,encoding='gbk',nrows=10,na_values='广州')   #dtype  设置数据类型  nrow前10行   na_values = 将其设置为缺失值
print(df,'\n\n\n')
print(df.head(10))   # 查看前10行  可在上面设置,也可在此设置

#3.2  保存数据csv,excel

#保存csv文件,excel文件
df.to_csv(r'E:\python练习合集\效果\61数据.csv',index=False,encoding='utf-8')  # 将索引去除

df.to_excel(r'E:\python练习合集\效果\61数据.xlsx',index=False,encoding='utf-8')

pd.concat([data1,data2],axis=0,ignore_index = True)  # 将data2的表拼接到data1的表中

#3.3 读取数据
excel = r'E:\python练习合集\小组作业\小组作业\202.xlsx'
df = pd.read_excel(excel,encoding = 'gbk',sheet_name='Sheet1')

##数据的筛选复符合列表的形式
print(df[0:10])

print(df.tail(5))  # 后5行

print(f'几行几列{df.shape}多少个元素{df.size}')

#查看每一列的元素
#第一种方式
print(df.姓名,df.学号)
#第二种方式  在后面加索引表示取多少行
print(df[['班主任','填表日期(如2020年2月15日)']][:5])
========================================================
#loc,iloc
#loc 已名称来取值
print(df.loc[0:6,['班主任','姓名']])  #loc [[行的标签],[所选列的标签]]    加[] 即在选择多少行,列 |不加[]即包含的全部行或者列
print(df.loc[[0,6],['班主任','姓名']])  # 出现 0,6

#选择想要的条件此条件不用加[]
choices = df.loc[df['性别']=='男',['姓名','学号']]
print(choices)


##  iloc 的使用跟loc区别不大,关键在于可运用数字的形式进行筛选条件,要在该位置的索引进行取值
print(df.iloc[:,[2,8]])  # 所有行,第2到第七列

#4.增删改查
excel = r'E:\python练习合集\小组作业\小组作业\202.xlsx'
df = pd.read_excel(excel,encoding = 'gbk',sheet_name='Sheet1')

IF = df[['班级','姓名']][(df['身体总体状况']=='健康') & (df['班级']=='d18c45')]    #先实现第一部分的功能,然后再找到班级的情况下 实现两个条件一起 找到全部行中身体健康,班级为d18c45的人  与mysql中类似,先写出效果,再选条件
print(IF)

#取范围值
IFF = df[['班级','姓名','学号']][df['班主任'].between(20,30,inclusive=True)]   #inclusive=True 实现左开右开 实现目的:再20到30范围内找到值
IFF = df[['班级','姓名','学号']][df['班主任'].between(10,20)]
print(IFF)

# 查看是否有该条件,筛选条件
choices_data = df[['姓名','学号','填表日期(如2020年2月15日)']][df['填表日期(如2020年2月15日)'].isin(['2020年5月1日'])]
# cd = df['填表日期(如2020年2月15日)'].str.contains('年')  # 查看是否包含年
print(choices_data)

#改
df['一天平均体温'] = (df['上午体温'] + df['下午体温'])/2
print(df)
df.loc[df['班主任'] =='王月梅','班主任'] = '王书记'   # 【df['班主任'] =='王月梅】原值 | '班主任'列名    [班主任] = 王月梅,【班主任】 = 新值
#修改列名
df.rename(columns={'填表日期(如2020年2月15日)':'日期'},inplace=True)  # 修改值{旧值:新值}
# df.rename(index = {},inplace=True)# 修改索引
print(df)


#删
del df['参数']
df.drop('一天平均体温',axis = 1,inplace=True)
print(df)

#增
yishangjunwu = df['新冠肺炎具体接触情况统计类型']
print(yishangjunwu)

DROP = df.drop('新冠肺炎具体接触情况统计类型',axis=1,inplace=True)
print(f"去除后的表格{df}\n\n")
INSERT = df.insert(11,'新冠肺炎具体接触情况统计类型',yishangjunwu)  # (位置,列名,数据)   11列之后
print(f'改完后的值{df}')


五、MySQL数据库的存入

1.利用pandas写入数据库
1.导入相关库
from sqlalchemy import create_engine  # 属于pandas中的数据库写入
2.连接数据库以及数据库的写入

engine = create_engine(‘dialect+driver://username:password@host:port/database’)

dialect – 数据库类型

driver – 数据库驱动选择

username – 数据库用户名

password – 用户密码

host 服务器地址

port 端口

database 数据库

#pandas 的写入数据库的方式
connect = create_engine('mysql+pymysql://root:992209050329.@win10:3306/数据库名称')
datas = [{"user":"MySQL"}]
df = pd.DataFrame(data=datas,columns=['列名'])
try:
    df.to_sql(name="tengxun",con=connect,index=False,if_exists="replace")   # 是否有该数据库,有就进行删除
except Exception:
	print("写入失败!")
print("写入成功!")
2.使用 pymysql 进行写入
import pymysql
#连接数据库
connect = pymysql.Connect(
    host="win10",
    port=3306,
    user="root",
    password="992209050329.",
    db="tengxzpw",
    charset="utf8"
)

#获取游标(cursor)
cursor=connect.cursor()

#sql 语句
sql = "select * from data1;"

#使用 excute() 的方法来执行 sql语句
cursor.execute(sql)

#使用fetchone来获取单挑数据
# result = cursor.fetchone()
# print(result)
#获取全部数据
results = cursor.fetchall()
print(results,type(results))

六、前端界面可视化

1.所要提供的数据
def find_mysql_data(self):
    result_list_data = []
    connect = pymysql.Connect(
    host="win10",
    port = 3306,
    db = "tengxun",
    user = "root",
    password = "992209050329.",
    charset = "utf-8"
    )
    cursor = connect.cursor()
    check = input("请输入所需要查询的字段:")   # 前端所加
    sql = f"select {check} from table_name"
    cursor.execute(sql)
    result_tuple = cursor.fetchall()  # 返回数据 (('教师',), ('数学教师',))
    for result in result_tuple:
    result_data = "".join(result)  # 将元组转换为字符串
    result_list_data.append(result_data)  # 变成我们图标所需要的列表数据

    return result_list_data

def pyecharts(self):   # 可视化图(三个图已饼图,柱状图为主)
    datas = self.find_mysql_data()
    print(datas)
2.视图
1.饼状图
# 饼图滚动图
from pyecharts import options as opts
from pyecharts.charts import Pie
from pyecharts.faker import Faker

c = (
    Pie()
    .add(
        "",
        [
            list(z)
            for z in zip(
                Faker.choose() + Faker.choose() + Faker.choose(),   # 一个 faker.choose就七个随机数据  为了创造多个数据
                Faker.values() + Faker.values() + Faker.values(),   # 一个 faker.choose就七个随机数据  为了创造多个数据
            )
        ],
        center=["40%", "50%"],    # 位置的宽度还有高度
    )
    .set_global_opts(
        title_opts=opts.TitleOpts(title="Pie-Legend 滚动"),
        legend_opts=opts.LegendOpts(type_="scroll", pos_left="80%", orient="vertical"),
        # 图例的类型。可选值:
        # 'plain':普通图例。缺省就是普通图例。
        # 'scroll':可滚动翻页的图例。当图例数量较多时可以使用
        # orient: vertical垂直的 horizontal:水平的
    )
    .set_series_opts(label_opts=opts.LabelOpts(formatter="{b}: {c}"))  # 标签显示的模式 已数据名称:数据值
    # 前端的一些小知识  https://blog.csdn.net/vv_eve/article/details/107991704
    # {a}:系列名。
    # {b}:数据名。
    # {c}:数据值。
    # {d}:百分比。
    # {per|{a}} 用{}框起来,前面的第一个per是样式设置,后面一个a代表系列名称,相当于说per样式修饰了竖线后面部分的样式
    .render("pie_scroll_legend.html")
)
2.柱状图
3.前端页面的编辑
1.index.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <title>我的登录界面</title>
    <link rel="stylesheet" href="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css">
    <style>
        body {
            background: url("../static/imgs/beijing2.jpg");
        }
        
        .form {
            background: rgba(255, 255, 255, 0.2);
            width: 400px;
            margin: 120px auto;
        }
        /*阴影*/
        
        .fa {
            display: inline-block;
            top: 27px;
            left: 6px;
            position: relative;
            color: #ccc;
        }
        
        input[type="text"],
        input[type="password"] {
            padding-left: 26px;
        }
        
        .checkbox {
            padding-left: 21px;
        }
    </style>

</head>

<body>
    <form method="POST" action="{{ url_for('Login') }}">
        <div class="container">
            <div class="form row">
                <div class="form-horizontal col-md-offset-3" id="login_form">
                    <h3 class="form-title">用户登录</h3>
                    <div class="col-md-9">
                        <div class="form-group">
                            <i class="fa fa-user fa-lg"></i> 用户名: <input class="form-control required" type="text" placeholder="请输入用户名" id="username" name="username" autofocus="autofocus" maxlength="5" />
                        </div>
                        <div class="form-group">
                            <i class="fa fa-lock fa-lg"></i> 手机号码: <input class="form-control required" type="number" placeholder="请输入手机号码" id="usernumber" name="usernumber" minlength="11" maxlength="11" />
                        </div>
                        <div class="form-group">
                            <label class="checkbox">
                                <input type="checkbox" name="remember" value="1"/>记住我
                            </label>
                        </div>
                        <div class="form-group col-md-offset-9">
                            <button type="submit" class="btn btn-success pull-right" name="submit">登录</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </form>
</body>

</html>

此码为转载篇!

2.select.html
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="http://cdn.static.runoob.com/libs/bootstrap/3.3.7/css/bootstrap.min.css">
    <title>第二个窗口</title>
    <style>
        body {
            background: url("../static/imgs/beijing2.jpg");
        }
        
        .form {
            background: rgba(255, 255, 255, 0.2);
            width: 400px;
            margin: 120px auto;
        }
        /*阴影*/
        
        .fa {
            display: inline-block;
            top: 27px;
            left: 6px;
            position: relative;
            color: #ccc;
        }
        
        input[type="text"],
        input[type="password"] {
            padding-left: 26px;
        }
        
        .checkbox {
            padding-left: 21px;
        }
        
        .my_selected {
            position: absolute;
            z-index: 1
        }
    </style>
</head>

<body>
    <form method="POST" action="{{ url_for('Select') }}">
        <div class="container">
            <div class="form row">
                <div class="form-horizontal col-md-offset-3" id="login_form">
                    <h3 class="form-title">请选择你所要查询的条件</h3>
                    <div class="col-md-9">
                        <div class="form-group">
                            <i class="fa fa-lock fa-lg"></i> 选择条件1
                            <select name="select">
                                <option class="my_selected">请选择你所想要查询的条件</option>
                                <option value="职位所研发的类型">研发的类型</option>
                                <option value="职位所在国家">国家</option>
                                <option value="职位所在城市">城市</option>
                                <option value="职位所发布的时间">时间</option>
                            </select>
                        </div>
                        <!-- <div class="form-group">
                            <i class="fa fa-lock fa-lg"></i> 密码: <input class="form-control required" type="password" placeholder="请输入密码" id="password" name="password" maxlength="8" />
                        </div>
                        <div class="form-group">
                            <label class="checkbox">
                                <input type="checkbox" name="remember" value="1"/>记住我
                            </label> -->
                        <!-- </div> -->
                        <div class="form-group col-md-offset-9">
                            <button type="submit" class="btn btn-success pull-right" name="submit">查询生成图</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </form>
</body>

</html>

七、Flask

1.简介

Flask是一个轻量级的可定制框架,使用Python语言编写,较其他同类型框架更为灵活、轻便、安全且容易上手。它可以很好地结合MVC模式进行开发,开发人员分工合作,小型团队在短时间内就可以完成功能丰富的中小型网站或Web服务的实现。另外,Flask还有很强的定制性,用户可以根据自己的需求来添加相应的功能,在保持核心功能简单的同时实现功能的丰富与扩展,其强大的插件库可以让用户实现个性化的网站定制,开发出功能强大的网站

在这里插入图片描述

pip install flask
pip install Jinja2
2.重定向

重定向:指定函数,也指到哪一个路由上,其中分为永久性重定向以及暂时性重定向

永久性重定向: code=301 多用于旧网址被废弃,要转到新的网址上去,典型案例 输入"www.jingdong.com" 会自动跳转到 “jd.com”

暂时性重定向:code = 302,即访问需要一个权限的网址是,如果当前用户没有登陆,会重定向到登陆到页面

@app.route('/user/')
def user_info():
    """用户个人中心"""
    name = request.args.get('name')
    if name:
        return '用户中心, 用户: {}'.format(name)
    else:
        # return redirect('/login/')  # 不建议这样做,写死了
        return redirect(url_for('login'), code=302)  # 没有取到用户名,重定向到登录页面  # login是函数


@app.route('/login/', methods=['GET', 'POST'])
def login():
    """登录页"""
    return 'login page登录页面'

此码为转载篇!

八、总结与效果

1.代码总结

爬虫

# encoding:utf-8
# 先查看原网页上有多少页
import requests
import parsel
import pandas as pd
import time
import datetime
import re
import random
import os
import csv
import json
import urllib.parse # 转换字符串与网络编码的库  # unquote(转换为中文) quote(转换为网络编码)

class tengxun:
    def __init__(self):
        self.url = "https://careers.tencent.com/tencentcareer/api/post/Query"    # 我们在网页上抓取到 url
        self.headers = {
        "user-agent":"Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36",
        "referer":"https://careers.tencent.com/search.html?keyword=%E8%AE%A1%E7%AE%97%E6%9C%BA"
    }
        # self.position = urllib.parse.quote(input("请输入所需要的职业:"))   # 输入一个 position的职位 并通过urllib库将中文转化为 url编码格式
    def massgaes(self,pages):
        parse ={
            "timestamp":str(round(time.time()*1000)),  # 时间切分成秒分数
            "keyword":"",    # 职位的名称
            "pageIndex":str(pages),  #页数
            "pageSize":"10",
            "language":"zh-cn",
            "area":"cn",
            "countryId":"",
            "cityId":"",
            "bgIds":"",
            "productId":"",
            "categoryId":"",
            "parentCategoryId":"",
            "attrId":""
        }
        return parse

    def url_data(self):
        global position_data
        position_data = []  # 储到的地方

        for pages in range(1,630):  # 爬取页数
            print(f"第 {pages} 页的爬取···")
            response = requests.get(url=self.url,headers = self.headers,params=self.massgaes(pages))
            start_time = datetime.datetime.now()
            time.sleep(random.uniform(0.1,3.9))     # 随机数的睡眠
            end_time = datetime.datetime.now()
            print(f"本次页面共花费:{(end_time-start_time).seconds} 秒")
            time.sleep(0.8)
            data = (response.json())  # json.loads   # dict类型的数据
            position_massages = data['Data']['Posts']
            # print("*"*30)
            # print(position_massages)
            # print("*" * 30)
            for position_massage in position_massages:
                position = position_massage['RecruitPostName'].strip()
                position_name = re.sub(pattern=r'\(.*?)',string=position,repl="")   # 职位名称
                position_location = position_massage['LocationName'].strip()     #职位城市
                position_product = position_massage['ProductName'].strip()         # 职位所研发的产品
                position_category = position_massage['CategoryName'].strip()         # 职位的类型
                times = position_massage['LastUpdateTime'].strip()            # 职位上挂的时间
                time_model = "%Y年%m月%d日"
                time_touple = time.strptime(times,time_model)             # 将我们所提取的时间以这个模板提取出我们的时间数据
                year,month,days = time_touple[:3]
                position_time = datetime.date(year,month,days)           # 清洗后的职位时间
                position_country = position_massage['CountryName'].strip()        # 职位国家
                responsibility = position_massage['Responsibility'].strip()       # 职位要求
                position_responsibility = re.sub(pattern=r'[\\n\\uf077\\t\\x]',string=responsibility,repl="")   # 清洗后的职位要求
                position_data_dict = {
                    "职位名称":position_name,
                    "职位所在国家":position_country,
                    "职位所在城市":position_location,
                    "职位所研究的类型":position_category,
                    "职位所研发的产品":position_product,
                    "职位所发布的时间":position_time,
                    "职位所发布的要求":position_responsibility
                }
                position_data.append(position_data_dict)   # 将信息添加到列表之中
            print(f"第 {pages} 页 爬取成功!")
            self.data_write()
        return position_data

    def data_write(self):
        print("============= 存储 =============")
        path = os.path.dirname(__file__)+'/'+'招聘信息.csv'  # 获得当前的路径
        f = open(file=path,mode="a",encoding="utf-8")
        f.close()
        # datas = position_data  # 给 global对象
        df = pd.DataFrame(data=position_data,columns=['职位名称','职位所在国家','职位所在城市','职位所研究的类型','职位所研发的产品','职位所发布的时间','职位所发布的要求'])
        df.to_csv(path)    # 将文件写入
        print("========== 写入成功! ==========")

if __name__ == '__main__':
    print("================= 爬虫 =================")
    tengxun().url_data()
    # print("================= 存储 =================")
    # tengxun().data_write()


flask

from flask import Flask,render_template,redirect,request,url_for
import pymysql
from pyecharts import options as opts
from pyecharts.charts import Bar,Pie,Tab,Line
import time

TEMPLATES_PATH = r"E:/python练习合集/爬虫专利/腾讯招聘网/Flask文件/templates"
app = Flask(__name__,template_folder=TEMPLATES_PATH)

#数据库的连接
connection = pymysql.Connect(
    host="win10",
    port=3306,
    db="tengxun",
    user="root",
    password="992209050329.",
    charset="utf8"
)
cursor = connection.cursor()  # 获得光标

@app.route('/',methods=['GET','POST'])
def Login():   # 首页
    if request.method == "POST":
        username = str(request.form.get("username"))
        userphone = int(request.form.get("usernumber"))
        usertime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        massgaes = {
            "用户姓名":username,
            "用户电话":userphone,
            "用户登陆的时间":usertime
        }
        sql = f'INSERT INTO users(user_name,user_phone,use_time) VALUES ("{username}",{userphone},"{usertime}");'
        cursor.execute(sql)
        connection.commit()

        print("已存储用户信息",massgaes)
        # print(f"字段的类型\nusername:{type(username)}\nuserphone:{type(userphone)}")
        return redirect(url_for("Select"))   # 如果存储成功则进行添加到数据库并转到下一页
    return render_template("index.html")   # 若是得不到信息就回到这里面进行再次登陆

@app.route("/select",methods=['GET','POST'])
def Select():  # 选择页面
    global result_data_list,data_name  # 为了把数据传给图里面
    result_data_list = []
    if request.method == "POST":
        data_name = request.form.get("select")   # 所要查询的语句
        # print(data)
        sql = f'select {data_name} from tx_table;'
        cursor.execute(sql)   # 提交我们的语句
        result_tuple = cursor.fetchall()
        for result in result_tuple:
            result_data = "".join(result)
            result_data_list.append(result_data)
        return redirect(url_for("Result"))
    return render_template("select.html")

@app.route("/result",methods=['GET','POST'])
def Result():
    global KEYS,VALUES
    datas = result_data_list
    result_datas = {}  # 已健值进行统计
    for i in set(datas):
        result_datas[i] = datas.count(i)
    print(result_datas)
    # 装数据的容器
    KEYS = []
    VALUES = []
    for keys,values in result_datas.items():
        KEYS.append(keys)
        VALUES.append(values)
    # 图的组合
    tab = Tab(page_title="职位数据统计图")
    tab.add(Bar_render(),"柱状数据统计图")
    tab.add(Line_render(),"折线数据统计图")
    tab.add(Pie_render(),"饼状数据统计图")
    tab.render("E:/python练习合集/爬虫专利/腾讯招聘网/Flask文件/templates/result.html")
    return render_template("result.html")

def Bar_render():
    bar = Bar(init_opts=opts.InitOpts(page_title="数据统计图",bg_color="#EFEBDC"))
    bar.add_xaxis(KEYS)
    bar.add_yaxis(data_name,VALUES)  # 设置一个 统计的函数
    bar.set_global_opts(title_opts=opts.TitleOpts(title="数据统计图"),
                        datazoom_opts=opts.DataZoomOpts(type_="slider"))
    return bar

def Pie_render():
    pie = Pie(init_opts=opts.InitOpts(page_title="数据统计图",bg_color="#EFEBDC"))
    pie.add("",[list(z) for z in zip(KEYS,VALUES)],rosetype="radius",label_opts=opts.LabelOpts(is_show=True),radius=["50%","70%"],center=["50%","58%"])
    pie.set_series_opts(label_opts=opts.LabelOpts(formatter="{b}:{c}\n百分比: {d}%"))
    return pie

def Line_render():
    line = Line(init_opts=opts.InitOpts(page_title="数据统计图",bg_color="#EFEBDC"))
    line.add_xaxis(KEYS)
    line.add_yaxis("",VALUES,markpoint_opts=opts.MarkPointOpts(data=[opts.MarkPointItem(type_="max")]),is_smooth=True)
    line.set_global_opts(title_opts=opts.TitleOpts(title="数据统计图"),
                         datazoom_opts=opts.DataZoomOpts(type_="slider"))

    return line
if __name__ == '__main__':
    app.run(debug=True)

2.实现效果

在这里插入图片描述



在这里插入图片描述



在这里插入图片描述



在这里插入图片描述



在这里插入图片描述

完结!
此篇部分装载!
内有不足,请指点!

  • 4
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
爬虫(Web Crawler)是一种自动化程序,用于从互联网上收集信息。其主要功能是访问网页、提取数据并存储,以便后续分析或展示。爬虫通常由搜索引擎、数据挖掘工具、监测系统等应用于网络数据抓取的场景。 爬虫的工作流程包括以下几个关键步骤: URL收集: 爬虫从一个或多个初始URL开始,递归或迭代地发现新的URL,构建一个URL队列。这些URL可以通过链接分析、站点地图、搜索引擎等方式获取。 请求网页: 爬虫使用HTTP或其他协议向目标URL发起请求,获取网页的HTML内容。这通常通过HTTP请求库实现,如Python中的Requests库。 解析内容: 爬虫对获取的HTML进行解析,提取有用的信息。常用的解析工具有正则表达式、XPath、Beautiful Soup等。这些工具帮助爬虫定位和提取目标数据,如文本、图片、链接等。 数据存储: 爬虫将提取的数据存储到数据库、文件或其他存储介质中,以备后续分析或展示。常用的存储形式包括关系型数据库、NoSQL数据库、JSON文件等。 遵守规则: 为避免对网站造成过大负担或触发反爬虫机制,爬虫需要遵守网站的robots.txt协议,限制访问频率和深度,并模拟人类访问行为,如设置User-Agent。 反爬虫应对: 由于爬虫的存在,一些网站采取了反爬虫措施,如验证码、IP封锁等。爬虫工程师需要设计相应的策略来应对这些挑战。 爬虫在各个领域都有广泛的应用,包括搜索引擎索引、数据挖掘、价格监测、新闻聚合等。然而,使用爬虫需要遵守法律和伦理规范,尊重网站的使用政策,并确保对被访问网站的服务器负责。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值