数据采集第二次实验

作业①:

    Gitee

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

  • 输出信息:
    序号 地区 日期 天气信息 温度
    1 北京 7日(今天) 晴间多云,北部山区有阵雨或雷阵雨转晴转多云 31℃/17℃
    2 北京 8日(明天) 多云转晴,北部地区有分散阵雨或雷阵雨转晴 34℃/20℃
    3 北京 9日(后台) 晴转多云 36℃/22℃
    4 北京 10日(周六) 阴转阵雨 30℃/19℃
    5 北京 11日(周日) 阵雨 27℃/18℃
    6......

    (1)爬取中国气象网网页内容

    实验过程
    1.创建weather.db数据库,(代码如下)

    class WeatherDB:
    
        def openDB(self):
            self.con=sqlite3.connect("weathers.db")
            self.cursor=self.con.cursor()
            try:
                self.cursor.execute("create table weathers (wCity varchar(16),wDate varchar(16),wWeather varchar(64),wTemp varchar(32),constraint pk_weather primary key (wCity,wDate))")
            except:
                self.cursor.execute("delete from weathers")
    
        def closeDB(self):
            self.con.commit()
            self.con.close()
    
        def insert(self, city, date, weather, temp):
            try:
                self.cursor.execute("insert into weathers (wCity,wDate,wWeather,wTemp) values (?,?,?,?)",
                                    (city, date, weather, temp))
            except Exception as err:
                print(err)
    
        def show(self):
                self.cursor.execute("select * from weathers")
                rows = self.cursor.fetchall()
                # print("%-16s%-16s%-32s%-16s" % ("city", "date", "weather", "temp"))
                for row in rows:
                    print("%-16s%-16s%-32s%-16s" % (row[0], row[1], row[2], row[3]))
    

    2.建立 WeatherForecast类,观察url:

    url = "http://www.weather.com.cn/weather/" + self.cityCode[city] + ".shtml"
    

    3.获取html,再爬取数据

    req = urllib.request.Request(url, headers=self.headers)
                        data = urllib.request.urlopen(req)
                        data = data.read()
                        dammit = UnicodeDammit(data, ["utf-8", "gbk"])
                        data = dammit.unicode_markup
                        soup = BeautifulSoup(data, "html.parser")
                        lis = soup.select("ul[class='t clearfix'] li")
                        for li in lis:
                            try:
                                date = li.select('h1')[0].text
                                weather = li.select('p[class="wea"]')[0].text
                                temp = li.select("p[class='tem']")[0].text.strip()
    

    运行结果

    心得体会:

    通过本次实验了解到了数据库的实现,爬虫较为简单

    作业②:

      Gitee

    • 要求:用requests和自选提取信息方法定向爬取股票相关信息,并存储在数据库中。

      候选网站:东方财富网:https://www.eastmoney.com/
      新浪股票:http://finance.sina.com.cn/stock/

      技巧:在谷歌浏览器中进入F12调试模式进行抓包,查找股票列表加载使用的url,并分析api
      返回的值,并根据所要求的参数可适当更改api的请求参数。根据URL可观察请求的参数f1、
      f2可获取不同的数值,根据情况可删减请求的参数。

    • 输出信息: | 序号 | 股票代码 | 股票名称 | 最新报价 | 涨跌幅 | 涨跌额 | 成交量 | 成交额 | 振幅 | 最高 | 最低 | 今开 | 昨收 | | ------- | ------ | ---- | ----- | ------ | ----- | ------ | ---- | ----- | ---- | ----- | ---- | ----- | | 1 | 688093 | N世华 | 28.47 | 62.22% | 10.92 | 26.13万 | 7.6亿 | 22.34 | 32.0 | 28.08 | 30.2 | 17.55 | | 2...... | | | | | | | | | | | | |

      (2)爬取股票相关信息

      实验过程
      1.在谷歌浏览器中进入F12调试模式进行抓包,查找股票列表加载使用的url

      url = "http://59.push2.eastmoney.com/api/qt/clist/get?cb=jQuery1124004035526877987472_1634114986169\
          &pn="+str(page)+"&pz=20&po=1&np=1&ut=bd1d9ddb04089700cf9c27f6f7426281&fltt=2&invt=2&fid=f3&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&_=1634114986170"
      

      2.用正则表达式提取数据

          data = gethtml(page)
                  str = data.decode('UTF-8')
                  # print(str)
                  Code = re.findall('"f12":"(.*?)"', str)
                  # print(Code)
                  Name = re.findall('"f14":"(.*?)"', str)
                  # print(Name)
                  Price = re.findall('"f2":(.*?),', str)
                  # print(Price)
                  Updown = re.findall('"f3":(.*?),', str)
                  # print(Updown)
                  Updownnumber = re.findall('"f4":(.*?),', str)
                  # print(Updownnumber)
                  Trade = re.findall('"f5":(.*?),', str)
                  # print(Trade)
                  Tradenumber = re.findall('"f6":(.*?),', str)
                  # print(Tradenumber)
                  Swing = re.findall('"f7":(.*?),', str)
                  # print(Swing)
                  Highest = re.findall('"f15":(.*?),', str)
                  # print(Highest)
                  Lowest = re.findall('"f16":(.*?),', str)
                  # print(Lowest)
                  Today = re.findall('"f17":(.*?),', str)
                  # print(Today)
                  Yesday = re.findall('"f18":(.*?),', str)
                  # print(Yesday)
                  for i in range(19):
                      index = i + 1
                      # print(dealprice)
                      self.db.insert(index, Code[i], Name[i], Price[i], Updown[i], Updownnumber[i], Trade[i],
                                     Tradenumber[i], Swing[i], Highest[i], Lowest[i], Today[i], Yesday[i])
      # 这里展示一部分
      

      3.利用数据库插入功能进行数据插入

      self.db.insert(index, Code[i], Name[i], Price[i], Updown[i], Updownnumber[i], Trade[i],
                                     Tradenumber[i], Swing[i], Highest[i], Lowest[i], Today[i], Yesday[i])
      

      至于创建数据库的过程与题目一类似,这里不做展示,见源代码
      运行结果

      心得体会

      本次作业与之前几次显然不同,刚刚开始感觉一头雾水,东方财富网页面包含的所有股票信息被分成了多个板块,导致我们无法直接通过网页的url爬取所有数据,因此本题采用动态抓包,使用f12进行抓包抓取js,分析得到数据对应的url就能实现爬取操作。紧接着可以通过严格的json格式,进行jsonSearch,或者正则表达式筛选信息都可以。

      作业③:

        Gitee

      • 要求:爬取中国大学2021主榜

        https://www.shanghairanking.cn/rankings/bcur/2021
        所有院校信息,并存储在数据库中,同时将浏览器F12调试分析的过程录制Gif加入至博客中。
        技巧:分析该网站的发包情况,分析获取数据的api


      • 输出信息:

        排名 学校 总分
        1 清华大学 969.2

        (3)爬取大学相关信息

        实验过程
        1.获取页面url

        url = "https://www.shanghairanking.cn/rankings/bcur/2021"
        

        2.对得到的数据进行正则匹配:

        name = r'class="name-cn" data-v-b80b4d60>(.*?) </a>'  # 匹配学校
                        score = r'<td data-v-6885f26d>\n.*?\n                    </td>'  # 匹配总分
                        namelist = re.findall(name, data)
                        scorelist = re.findall(score, data)
                        for i in range(len(scorelist)):
                            ulist.append([i+1, namelist[i], scorelist[i].split("\n")[1].strip()])
        

        3.插入数据库(一样的操作)

                        for i in ulist:
                            rank = i[0]
                            name = i[1]
                            score = i[2]
                            self.db.insert(rank,name,score)
        

        运行结果

        心得体会

        第三题所用的技术采用正则表达式分析。

        gif:

posted @ 2021-10-26 22:33  抱着欣欣看月亮  阅读(85)  评论(0编辑  收藏  举报