2023数据采集与融合技术实践作业二

发布时间 2023-10-17 15:41:04作者: I服了U123

第二次作业

一、作业内容

  • 作业①:
    • 要求:在中国气象网(http://www.weather.com.cn)给定城市集的7日天气预报,并保存在数据库。
    • 输出信息:
    • Gitee文件夹链接:第一个作业代码及文件
    • 1)作业代码和图片:

            代码内容:

    • import requests
      from bs4 import BeautifulSoup
      import urllib.request
      import urllib.parse
      import bs4
      import re
      import sqlite3
      def main():
          #更改头部信息模拟浏览器访问
          headers = {
              "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36"
          }
          #设置搜索关键词
          city=('101010100', '101020100','101280101','101280601')
          diqu1=('北京','上海','广州','深圳')
          # http: // www.weather.com.cn / weather / 101010100.shtml
          #将中文转换为url编码
          #初始化下载页数显示
          a = 1
          b=0
          xuhao=1
          weather2=[]
          # 循环遍历每一页
          # 创建数据表
          conn = sqlite3.connect('weather.db')
          cursor = conn.cursor()
          cursor.execute('''
             create table IF NOT EXISTS  weather1(
                 di text,
                 riqi text,
                 tianqi text,
                 wendu text)
             ''')
          for i in range(0,4):
              #获取url内容并把它做成完整的一锅汤
              # http: // www.weather.com.cn / weather / 101010100.shtml
              # url = requests.get(f"http://www.weather.com.cn/weather/{city[b]}.shtml", headers=headers)
              url = requests.get(f"http://www.weather.com.cn/weather/{city[i]}.shtml", headers=headers)
      
      
              url.encoding=url.apparent_encoding
              htm = url.text
              soup = BeautifulSoup(htm, 'html.parser')
              # print(soup.prettify())
      
              for dayweather in soup.find_all('ul', 't clearfix'):
                  if isinstance(dayweather,bs4.element.Tag):
                      # print(dayweather.prettify())
                      # 日期
                      date=dayweather.find_all('h1')
                      # print(date[0].string)
                      # 天气信息
                      tianqi=dayweather.find_all('p','wea')
                      # 温度
                      tem=soup.find_all('p', 'tem')
                      # 爬取最高温度
                      tem2=[]
                      for tag in tem:
                          tem1= tag.find_all('span')
                          tem2.extend(tem1)
                      # 防止晚上访问不了
                      tem2.extend(tem1)
                      # print(tem2)
                      # 爬取最低温度
                      tem3=[]
                      for tag in tem:
                          tem4= tag.find_all('i')
                          tem3.extend(tem4)
                      # print(tem3)
                      # print(tem[0].span.string)
                      # print(tianqi[3].string)
                      for cishu in range(0,7):
      
                          riqi=date[cishu].string
                          # print(riqi)
                          weather=tianqi[cishu].string
                          # print(weather)
                          wendu=tem2[cishu].string
                          # print(wendu)
                          wendu1=tem3[cishu].string
                          # print(wendu1)
                          zongwendu=wendu+'/'+wendu1
                          # print(zongwendu)
                          # weather.append([xuhao,diqu[b],date[cishu].string,tianqi[cishu].string,tem[cishu].span.string,tem[cishu].i.string])
                          cursor.execute("INSERT INTO weather1 (di, riqi, tianqi, wendu) VALUES (?, ?, ?, ?)",(diqu1[b], riqi, weather, zongwendu))
      
       # print(weather)
      
      
              b=b+1
          conn.commit()
          cursor.close()
          conn.close()
      main()

      输出结果图片:

    • 2)心得体会:

            学会了如何对数据保存到数据表当中,我选择了SQLite数据库作为数据存储的方式。SQLite是一种轻量级的嵌入式数据库,适用于小规模的数据存储需求。使用SQLite可以方便地进行数据的插入、查询和更新,同时不需要额外的数据库服务器。代码中创建了名为"weather1"的数据表,用于存储天气信息。通过execute()方法执行SQL语句,插入数据到数据表中。这种数据库设计和操作方式简单高效,适用于小型项目和简单数据结构的存储需求。

  • 作业②
    • 要求:用requests和BeautifulSoup库方法定向爬取股票相关信息,并存储在数据库中。
    • 候选网站:东方财富网:https://www.eastmoney.com/
    • 新浪股票:http://finance.sina.com.cn/stock/
    • 技巧:在谷歌浏览器中进入F12调试模式进行抓包,查找股票列表加载使用的url,并分析api返回的值,并根据所要求的参数可适当更改api的请求参数。根据URL可观察请求的参数f1、f2可获取不同的数值,根据情况可删减请求的参数。
    • 参考链接:https://zhuanlan.zhihu.com/p/50099084
    • 输出信息:
    • Gitee文件夹链接:第二个作业代码及文件
    • 1)作业代码和图片:

            代码内容:

    • import requests
      from bs4 import BeautifulSoup
      import bs4
      import re
      import urllib.request
      import urllib.parse
      import sqlite3
      
      
      #将url信息从网络中爬取下来,并且将它其中的html页面返回给其他的函数
      def getHTMLText(url):
          try:
              r = requests.get(url, timeout=30)
              r.raise_for_status()
              r.encoding = r.apparent_encoding
              return r.text
          except:
              return "getHTMLText(url) error"
      
      def main():
          # 创建数据表
          conn = sqlite3.connect('gupiao.db')
          cursor = conn.cursor()
          cursor.execute('''
          create table IF NOT EXISTS  gupiao1(
              股票代码 text,
              股票名称 text,
              最新报价 text,
              涨跌幅 text,
              涨跌额 text,
              成交量 text,
              成交额 text,
              振幅 text,
              最高 text,
              最低 text,
              今开 text,
              昨收 text)
          ''')
          # 爬多少页只需要改这里的次数,这里爬取前20页进行展示
          for a in range(1, 20):
              url = f'https://97.push2.eastmoney.com/api/qt/clist/get?cb=jQuery112406318197805742447_1697478765438&pn={a}&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&wbp2u=|0|0|0|web&fid=f3&fs=m:0+t:6,m:0+t:80,m:1+t:2,m:1+t:23,m:0+t:81+s:2048&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&_=1697478765439'
              html = getHTMLText(url)
              # print(html)
              # 股票代码
              gupiaodaima=re.findall(r'\"f12\"\:\".*?\"',html)
              # print(gupiaodaima)
              # 股票名称
              gupiaomingcheng=re.findall(r'\"f14\"\:\".*?\"',html)
              # print(gupiaomingcheng)
              # 最新报价
              zuixinbaojia=re.findall(r'\"f2\"\:[\d\.]*',html)
              # print(zuixinbaojia)
              # 涨跌幅
              zhangdiefu=re.findall(r'\"f3\"\:[\d\.]*',html)
              # print(zhangdiefu)
              # 涨跌额
              zhangdiee=re.findall(r'\"f4\"\:[\d\.]*',html)
              # print(zhangdiee)
              # 成交量
              chengjiaoliang=re.findall(r'\"f5\"\:[\d\.]*',html)
              # print(chengjiaoliang)
              # 成交额
              chengjiaoe=re.findall(r'\"f6\"\:[\d\.]*',html)
              # print(chengjiaoe)
              # 振幅
              zhenfu=re.findall(r'\"f7\"\:[\d\.]*',html)
              # print(zhenfu)
              # 最高
              zuigao = re.findall(r'\"f15\"\:[\d\.]*', html)
              # print(zuigao)
              # 最低
              zuidi = re.findall(r'\"f16\"\:[\d\.]*', html)
              # print(zuidi)
              # 今开
              jinkai=re.findall(r'\"f17\"\:[\d\.]*', html)
              # print(jinkai)
              # 昨收
              zuoshou=re.findall(r'\"f18\"\:[\d\.]*', html)
              # print(zuoshou)
              for i in range(len(gupiaodaima)):
                  gupiaodaima1=eval(gupiaodaima[i].split(':')[1])
                  gupiaomingcheng1=eval(gupiaomingcheng[i].split(':')[1])
                  zuixinbaojia1=eval(zuixinbaojia[i].split(':')[1])
                  zhangdiefu2=eval(zhangdiefu[i].split(':')[1])
                  zhangdiefu1=str(zhangdiefu2)+"%"
                  zhangdiee1=eval(zhangdiee[i].split(':')[1])
                  chengjiaoliang1=eval(chengjiaoliang[i].split(':')[1])
                  chengjiaoe1=eval(chengjiaoe[i].split(':')[1])
                  zhenfu2=eval(zhenfu[i].split(':')[1])
                  zhenfu1=str(zhenfu2)+"%"
                  zuigao1=eval(zuigao[i].split(':')[1])
                  zuidi1=eval(zuidi[i].split(':')[1])
                  jinkai1=eval(jinkai[i].split(':')[1])
                  zuoshou1=eval(zuoshou[i].split(':')[1])
                  cursor.execute("INSERT INTO gupiao1 (股票代码, 股票名称,最新报价 ,涨跌幅,涨跌额,成交量,成交额,振幅,最高,最低,今开,昨收) VALUES (?, ?, ?, ?,?,?,?,?,?,?,?,?)",(gupiaodaima1,gupiaomingcheng1,zuixinbaojia1,zhangdiefu1,zhangdiee1,chengjiaoliang1,chengjiaoe1,zhenfu1,zuigao1,zuidi1,jinkai1,zuoshou1))
      
      
          conn.commit()
          cursor.close()
          conn.close()
      main()

      输出结果图片:

    • 2)心得体会:

        通过本次作业,使我对网络请求,HTML解析,正则表达式,数据处理和转换以及SQLite数据库操作更加熟悉了,流程如下:首先导入所需的库,定义函数getHTMLText(url):该函数用于发送网络请求,获取URL对应的HTML页面。通过requests库发送GET请求,设置超时时间和编码方式,如果请求成功,则返回HTML页面的文本内容;如果请求失败,则返回错误信息。然后定义主函数main():在主函数中,首先创建了一个SQLite数据库连接,并创建了一个名为"gupiao1"的数据表,用于存储股票数据。循环爬取多页数据:通过for循环控制爬取的页数,这里设置为爬取前20页的数据。在每次循环中,构造了一个特定的URL,其中包含了页数的参数。然后调用getHTMLText函数获取HTML页面的文本内容。使用正则表达式提取数据:通过使用re库的findall函数和正则表达式,从HTML页面中提取股票数据的各个字段,如股票代码、股票名称、最新报价等。使用split和eval函数对提取的数据进行处理和转换,例如去除冒号和引号,转换为相应的数据类型。数据插入数据库:将提取和处理后的数据插入到SQLite数据库的相应字段中。使用cursor.execute函数执行SQL插入语句,将数据添加到数据表"gupiao1"中。通过conn.commit()提交对数据库的修改,并通过cursor.close()和conn.close()关闭数据库连接。

  • 作业③:
    • 要求:爬取中国大学2021主榜(https://www.shanghairanking.cn/rankings/bcur/2021)所有院校信息,并存储在数据库中,同时将浏览器F12调试分析的过程录制Gif加入至博客中。
    • 技巧:分析该网站的发包情况,分析获取数据的api
    • 输出信息:
    •               排名

                    学校

                    省市

                    类型

                    总分

                    1

                    清华大学

                    北京

                    综合

                    969.2

       
       
  • Gitee文件夹链接:第三个作业代码及文件
  • 浏览器F12调试分析的过程:
  •  

  •  1)作业代码和图片:

          代码内容:

  • import requests
    from bs4 import BeautifulSoup
    import bs4
    import re
    import urllib.request
    import urllib.parse
    import sqlite3
    
    
    #将url信息从网络中爬取下来,并且将它其中的html页面返回给其他的函数
    def getHTMLText(url):
        try:
            r = requests.get(url, timeout=30)
            r.raise_for_status()
            r.encoding = r.apparent_encoding
            return r.text
        except:
            return "getHTMLText(url) error"
    
    def main():
        # 创建数据表
        conn = sqlite3.connect('school.db')
        cursor = conn.cursor()
        cursor.execute('''
        create table IF NOT EXISTS  student3(
            xuexiao text,
            shengshi text,
            leixing text,
            zongfen text)
        ''')
    
        url = 'https://www.shanghairanking.cn/_nuxt/static/1697106492/rankings/bcur/2021/payload.js'
        html = getHTMLText(url)
        provincelist = {
            'k': '江苏', 'n': '山东', 'o': '河南', 'p': '河北', 'q': '北京', 'r': '辽宁', 's': '陕西', 't': '四川',
            'u': '广东',
            'v': '湖北', 'w': '湖南', 'x': '浙江', 'y': '安徽', 'z': '江西', 'A': '黑龙江', 'B': '吉林', 'C': '上海',
            'D': '福建', 'E': '山西',
            'F': '云南', 'G': '广西', 'I': '贵州', 'J': '甘肃', 'K': '内蒙古', 'L': '重庆', 'M': '天津', 'N': '新疆',
            'Y': '海南'
        }
    
        typelist = {
            'f': '综合',
            'e': '理工',
            'h': '师范',
            'm': '农业',
            'T': '林业',
        }
        # 学校
        plt = re.findall(r'univNameCn\:\".*?\"', html)
        # print(plt)
        # 总分
        score = re.findall(r'score:(.*?),', html)
        # 省市
        province = re.findall(r'province:(.*?),', html)
        # print(province)
        # 类型
        leixin = re.findall(r'univCategory\:.*?\,', html)
        # print(leixing)
        # print(provincelist['q'])
        for i in range(len(province)):
            xuexiao = eval(plt[i].split(':')[1])
            zongfen1=score[i]
            # print(zongfen1)
            shengshi2 = province[i]
            shengshi = provincelist.get(shengshi2,'unknown')
            # print(shengshi)
            leixing1 = leixin[i].split(':')[1]
            leixing2 = leixing1.split(',')[0]
            leixing = typelist.get(leixing2, 'unknown')
            cursor.execute("INSERT INTO student3 (xuexiao, shengshi, leixing, zongfen) VALUES (?, ?, ?, ?)",(xuexiao, shengshi, leixing, zongfen1))
            # print(leixing)
        # printUnivList(uinfo,30)
        conn.commit()
        cursor.close()
        conn.close()
    main()

    输出结果图片:

  • 2)心得体会:

       这题主要就是通过正则表达式去匹配大学排名的相关信息,同时由于省市和类型是通过字符保存,所以要创建相应的字典映射来匹配他们的内容,并将提取的数据存储到SQLite数据库中。在爬取到的数据中,可能需要进行一些处理和转换,例如去除无用的字符、转换数据类型等。通过字符串处理方法和函数,如split()eval(),可以对数据进行处理和转换,以符合需求。通过合理的库的选择和使用,可以高效地获取和处理所需的数据。同时,代码中的异常处理和数据库操作也是编写网络爬虫时需要考虑的重要方面。