1. 程式人生 > 其它 >資料採集與融合技術-實驗二

資料採集與融合技術-實驗二

作業①:


    我的Gitee
  • 要求:在中國氣象網

    http://www.weather.com.cn
    給定城市集的7日天氣預報,並儲存在資料庫。

  • 輸出資訊:
    序號 地區 日期 天氣資訊 溫度
    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"))
                # print(“{0:{4}^16}{1:{4}^16}{2:{4}^32}{3:{4}^32}”.format(“city”,“date”,“weather”,“temp”,chr(12288)))
                tplt = "{0:^10}\t{1:{4}^9}\t{2:{4}^16}\t{3:^7}"
                print("{0:^12}\t{1:^13}\t{2:^19}\t{3:^0}".format("city", "date", "weather", "temp", chr(12288)))
                for row in rows:
                    # print("%-16s%-16s%-32s%-16s" % (row[0], row[1], row[2], row[3]))
                    print(tplt.format(row[0], row[1], row[2], row[3], chr(12288)))
    

    2.建立 WeatherForecast類,通過觀察url,得到以下程式碼:

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

    設定citycode

    self.cityCode = {"北京": "101010100", "福州": "101230101", "武漢": "101230101", "香港": "101320101"}
    

    3.通過urllib.request方法獲取html,在通過beautiful soup方法爬取資料

    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, "lxml")
                        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()
    

    執行結果

    心得體會:

    通過本次實驗瞭解到了建立資料庫的類方法實現,至於爬蟲部分運用的是之前經常使用的beautiful soup方法,較為熟練。

    作業②:


      我的Gitee
    • 要求:用requests和自選提取資訊方法定向爬取股票相關資訊,並存儲在資料庫中。

      候選網站:東方財富網:https://www.eastmoney.com/
      新浪股票:http://finance.sina.com.cn/stock/

      技巧:在谷歌瀏覽器中進入F12除錯模式進行抓包,查詢股票列表載入使用的url,並分析api
      返回的值,並根據所要求的引數可適當更改api的請求引數。根據URL可觀察請求的引數f1、
      f2可獲取不同的數值,根據情況可刪減請求的引數。

      參考連結:[https://gitee.com/chen-benyuan/CHEN/blob/master/實驗二/實驗二作業三.py)


    • 輸出資訊:
      序號 股票程式碼 股票名稱 最新報價 漲跌幅 漲跌額 成交量 成交額 振幅 最高 最低 今開 昨收
      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.匯入JsonSearch,先通過正則表示式拆枝,將不是json格式的部分去除,在利用
      jsondata = JsonSearch(object=json2, mode='j'),呼叫jsondata=search_all_value方法

      pat = "jQuery1124004035526877987472_1634114986169    \((.*?)\)"
              str1 = re.compile(pat,re.S).findall(str)[0]
              json2 = json.loads(str1)
              jsondata = JsonSearch(object=json2, mode='j')
              Symbollist = jsondata.search_all_value(key='f12')
              namelist = jsondata.search_all_value(key='f14')
      # 這裡展示一部分
      

      3.利用資料庫插入功能進行資料插入

      self.db.insert( index,Symbollist[i], namelist[i], LastTradelist[i], Chglist[i], Changelist[i], Volume, Turnover, slist[i], helist[i], lelist[i], Openlist[i], PrevCloselist[i])
      

      至於建立資料庫的過程與題目一類似,這裡不做展示,見原始碼
      執行結果

      心得體會

      本次作業與之前幾次顯然不同,剛剛開始感覺一頭霧水,東方財富網頁面包含的所有股票資訊被分成了多個板塊,導致我們無法直接通過網頁的url爬取所有資料,因此本題採用動態抓包,使用f12進行抓包抓取js,分析得到資料對應的url就能實現爬取操作。緊接著可以通過嚴格的json格式,進行jsonSearch,或者正則表示式篩選資訊都可以。

      作業③:


        我的Gitee
      • 要求:爬取中國大學2021主榜(https://www.shanghairanking.cn/rankings/bcur/2021)所 有院校資訊,並存儲在資料庫中,同時將瀏覽器F12除錯分析的過程錄製Gif加入至部落格中。 技巧:分析該網站的發包情況,分析獲取資料的api
      • 輸出資訊:
        排名 學校 總分
        1 清華大學 969.2

        (3)爬取大學相關資訊

        實驗過程
        1.一頁20個大學,可以考慮翻頁,但也可以選擇用抓包的方法,獲取js

        url = "https://www.shanghairanking.cn/_nuxt/static/1632381606/rankings/bcur/2021/payload.js"
        

        2.對抓包得到的資料進行正則匹配:

        score = r'score:(.*?),'
                        scorelist = re.findall(score,data)
                        # print(scorelist)
                        name = r'univNameCn:"(.*?)"'
                        namelist = re.findall(name,data)
        

        部分學校總分資料有異常採用如下方法處理

         for i in range(len(namelist)):
                            try:
                                if 'a'<=scorelist[i]<='z' or 'A'<=scorelist[i]<='Z':
                                    ulist.append([i+1,namelist[i], "--"])
                                else:
                                    ulist.append([i + 1, namelist[i], scorelist[i]])
        

        原本以為是混入了亂碼直接用--代替,後來發現與整個js檔案首尾的鍵值對有關所以又做了以下處理:

                        key = re.findall(r'function\((.*?)\)', data)  # 獲取鍵
                        str = ''.join(key)
                        key2 = str.split(',')
                        # print(key2)
                        value = re.findall(r'"",(.*?)\)', data)
                        str2 = ''.join(value)
                        # print(str2)
                        str3 = str2.replace('"',"")
                        # print(str3)
                        value2 = str3.split(',')
                        # print(value2) # 獲取值
        

        獲取了鍵值對後與srocelist和ranklist進行比較(這裡特別處理了"h:一流學科"的錯誤)

                        for i in range(len(scorelist)):
                            for j in range(len(key2)):
                                if scorelist[i]==key2[j]:
                                    scorelist[i]=value2[j]
                                elif ranklist[i]==key2[j]:
                                    ranklist[i]=value2[j]
        
                        ranklist[210] = "211"
        

        3.插入資料庫(一樣的操作)
        執行結果

        更改後的結果

        可以與上面的結果進行對比,完美解決。(這裡的圖樣式和上面的不太一樣,原因是pycharm出了點毛病,被我重灌了)

        心得體會

        第三題所用的技術與第二題類似,本次實驗對於抓包有了全面的認識,第二題用search_all_value分析js,第三題則採用另一種正則表示式分析。

        gif: