数据采集第二次实践

作业一

天气数据爬取实验

作业内容

在中国气象网(http://www.weather.com.cn)给定城市集的7日天气预报,并保存在数据库

实践过程

  1. 信息定位

    F12查看页面元素后发现,所需信息位于ul下的li标签中
    数据采集第二次实践

    li标签中元素较少,且信息较为简单,所以直接使用li.text获取字符串后,再对每个信息进行截取即可

    for li in soup.find('ul', attrs={"class": "t clearfix"}).children:
        if isinstance(li, element.Tag):
            winfo = []
            info = li.text
            si = info.split("\n")
            for i in si:
                if (i != ""):
                    winfo.append(i)
                    infos.append(winfo)
    
  2. 数据保存

    利用pyodbc库实现对SQL Server数据库的写入操作

    def save_to_mytsql(result):
        # 数据库连接
        conn = pyodbc.connect('DRIVER={SQL Server};SERVER=(local);DATABASE=test;UID=DESKTOP-FG7JKFI\捷;PWD=29986378;Trusted_Connection=yes')
        cur = conn.cursor()
        i=1;
        # 数据写入
        for s in result:
            sql='insert into weather([地区],[日期], [天气信息],[温度]) values(?,?,?,?)'
            cur.execute(sql,("福州",s[0],s[1],s[2]))
            print(s[0])
            i+=1
        conn.commit()
        conn.close()
    

作业结果

作业一源代码链接

  • 控制台输出:
    数据采集第二次实践

  • 数据库查询:
    数据采集第二次实践

心得体会

遇到子标签较少的情况,可直接利用text获取所有数据后进行分割得到所需数据。

作业二

股票数据爬取实验

作业内容

用requests和自选提取信息方法定向爬取股票相关信息,并存储在数据库中。东方财富网:https://www.eastmoney.com

实践过程

  1. 抓包与链接规律寻找

    F12网页抓包结果如下:
    数据采集第二次实践

    查看请求链接:
    数据采集第二次实践

    翻页抓取不同的包后发现 翻页参数为pn

    板块切换可通过传入参数cmd来实现

    故请求部分链接代码如下:

    cmd = {
        "上证指数":"C.1",
        "深圳指数":"C.5",
        "沪深A股":"C._A",
        "上证A股":"C.2",
        "深圳A股":"C._SZAME",
        "新股":"C.BK05011",
        "中小板":"C.13",
        "创业板":"C.80"}
    
    url = "http://85.push2.eastmoney.com/api/qt/clist/get?cb=jQuery1124007120583477941156_1634089185302&pn="+str(page)+"&cmd="+cmd+"&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&fid=f11&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23&fields=f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,f24,f25,f22,f11,f62,f128,f136,f115,f152"
    r = requests.get(url)
    
  2. 信息爬取与规范化

    先将存储股票信息的data部分从字符串中截取出来

    pat = '"diff":\[(.*?)\]'
    data = re.compile(pat,re.S).findall(r.text)
    

    再对截取出的信息进行规范化:

    • 经过观察可发现,每个{}中存储一支股票的信息,故考虑利用字符串split()方法先将不同股票分开

    • 后利用json.load方法将字符串转换为字典形式便于后续数据提取

    • 最后可直接通过字典key值找到对应value值

    具体实现方法:

    data = getHtml(cmd,page)
    # 每一支股票分开
    datas = data[0].split('},')
    infos = []
    for info in datas:
        if info[-1]!="}":
            info = info+"}"
            # 将字符串转换为字典形式
            infos.append(json.loads(info))
    
  3. 信息输出

    控制台输出方式与上次实验相似,不具体赘述。

    数据库保存,利用pyodbc库实现对SQL Server数据库的写入操作

    def save_to_mytsql(result):
        # 数据库连接
        conn = pyodbc.connect('DRIVER={SQL Server};SERVER=(local);DATABASE=test;UID=DESKTOP-FG7JKFI\捷;PWD=29986378;Trusted_Connection=yes')
        cur = conn.cursor()
        i=1;
        # 数据写入
        for stock in result:
            sql='insert into stock([代码],[名称],[最新价格],[涨跌幅],[涨跌额],[成交量],[成交额],[振幅],[最高],[最低]) values(?,?,?,?,?,?,?,?,?,?)'
            cur.execute(sql,(stock[0],stock[1],stock[2],stock[3],stock[4],stock[5],stock[6],stock[7],stock[8],stock[9]))
            i+=1
        conn.commit()
        conn.close()
    

作业结果

作业二源代码链接

  • 控制台输出
    数据采集第二次实践

  • 数据库查询
    数据采集第二次实践

心得体会

一次页面刷新会有许多请求,善用筛选器可以帮助我们更快速寻找到需要的包。

字符串转字典方式:利用json.load()。但是该方法存在限制,所有的key值需要用双引号包裹,不然无法正确解析,会报错。

作业三

大学排名爬取实验

作业内容

爬取中国大学2021主榜(https://www.shanghairanking.cn/rankings/bcur/2021 )所有院校信息,并存储在数据库中,同时将浏览器F12调试分析的过程录制Gif加入至博客中。

实践过程

  1. 题目分析与方法选择

    院校排名其实已经爬取多次,但这次与之前几次的不同之处在于这次需要爬取所有院校信息,故使用翻页的方法较为繁琐,所以选择采用直接抓取json包一次性获取所有排名信息。

    抓取过程如下:

    数据采集第二次实践

  2. 爬取数据规范化处理

    由于数据中存在多对大括号,故截取信息的正则表达式为

    pat = 'univData:\[(\{.*?\})\]'
    data = re.compile(pat, re.S).findall(r.text)
    

    本题与上一题数据的差别在于,key值未用双引号,故不可直接将字符串转换为字典,所以选择使用re库来获取所需内容。

    data = getHtmlByUrlib(url)
    datas = data[0].split('},')
    infos =[]
    for school in datas:
        name = re.search(r'univNameCn:"(.*?)"',school).group(1) # 获取院校名
        score = re.search(r'score:(\d*\.*\d*)',school).group(1) # 获取总分
        # 部分院校总分未统计
        if score=="":
            score = '未知'
            infos.append([name,score])
    

    对爬取数据进行观察发现,院校总分存在空值,使用“'未知'对空值进行填充

  3. 数据输出与保存

    数据保存至数据库:

    conn = pyodbc.connect('DRIVER={SQL Server};SERVER=(local);DATABASE=test;UID=DESKTOP-FG7JKFI\捷;PWD=29986378;Trusted_Connection=yes')
    cur = conn.cursor()
    i=1;
    # 数据写入
    for s in result:
        sql='insert into school([ranknum],[name], [score]) values(?,?,?)'
        cur.execute(sql,(i,s[0],s[1]))
        print(s[0])
        i+=1
        conn.commit()
        conn.close()
    

作业结果

作业三源代码链接

  • 控制台输出
    数据采集第二次实践

  • 数据库查询
    数据采集第二次实践

心得体会

本题在刚开始尝试时想沿用第二题的思路,但发现一些问题。一是信息截取部分,由于信息中还存在一组{},直接用问题二会导致信息截取不全,故将表达式修改为匹配[{}]形式;二是本想直接转换为字典,但是却发现key值格式错误,无法正确转换,所以最后还是使用了re进行匹配。

如果一次要爬取全部的数据,直接抓包要比翻页爬取更加方便。

上一篇:day 42 常用的四种IO模型


下一篇:python3测试AD用户账号密码