整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          爬蟲實踐:爬取城市AQI實時報和日報數據

          爬蟲實踐:爬取城市AQI實時報和日報數據

          首發創作賽#

          有粉絲經常私信于我,咨詢網絡爬蟲的技巧。網絡爬蟲,有許多現成的框架,每個框架都有優缺點。如果要精通網絡爬蟲,就需要有html和javascript知識的積累。如果沒有,就得學習,否則......其實網上也流傳著爬取城市空氣質量數據的方法的博客和文章,但是爬取的網站不同,方法也各異,有的不是爬取的權威網上的數據,來源也各異,具體數據來使用需要謹慎。

          本人主要是想,通過不同案例,給粉絲展示不同網站爬取信息的應用技巧。本文章主要是向大家介紹,使用requests獲取權威網站公開發布的信息,不存在不能公開傳播的問題。并使用bs4解析爬取,城市AQI信息,即爬取AQI實時報和AQI日報?,F在整理出來分享給給大家。廢話不說了,直入主題。如果有不懂得地方,可以參考我以前寫的幾篇爬蟲文章。

          一、目標網站

          目標網址:https://www.mee.gov.cn/

          二、分析網站數據組織形式

          用瀏覽器打開https://www.mee.gov.cn/網站,如下圖所示:

          將瀏覽器進入調試模式,如下圖所示。

          分析其網頁html代碼,左邊紅框顯示的是AQI實時報和AQI日報的內容,右邊紅框顯示是對應的html的代碼。

          <iframe id="indexKqZlIframe" scrolling="no" src="http://datacenter.mee.gov.cn/websjzx/homepages/airDatas.vm" frameborder="0" width="100%"></iframe>

          需要指出的是:在進行爬取網站數據的時候,要有一定的html知識,這樣才能有效地分析網頁代碼。

          IFRAME是HTML標簽,作用是文檔中的文檔,或者浮動的框架(FRAME)。iframe元素會創建包含另外一個文檔的內聯框架(即行內框架)。簡而言之,就是嵌套一個子網頁內容。

          而這個網頁的內容的地址是:
          http://datacenter.mee.gov.cn/websjzx/homepages/airDatas.vm。這是正確爬取全國城市空氣質量指數AQI至關重要的一步。

          三、實現過程

          第一步:導入庫

          import requests
          from bs4 import BeautifulSoup

          第二步:獲取網頁源代碼

          除了網站的不同個,和我前面頭條的文章講過的一模一樣。

          url='http://datacenter.mee.gov.cn/websjzx/homepages/airDatas.vm'
          response=requests.get(url)
          page=response.content.decode()

          第三步:解析網頁

          1.html5lib方式解析信息

          這個就不啰嗦了,我前面頭條的文章已經細講過了。

          # 構建bs對象
          soup=BeautifulSoup(page, 'html5lib') 

          2.獲取AQI實時報和AQI日報的具體日期

          通過分析網站返回的內容,AQI實時報和AQI日報的具體日期,如下圖紅色箭頭所示:

          AQI實時報的具體日期,在id="tempdrhour"的<div></div>圖層中。

          AQI日報的具體日期,在id="tempdrday"的<div></div>圖層中。

          代碼如下:

          #AQI實時報的具體日期
          aqi_hour_date=soup.find(id='tempdrhour').text
          #AQI日報的具體日期
          aqi_day_date=soup.find(id='tempdrday').text

          通過尋找id="tempdrhour"的text內容,得到AQI實時報的具體日期aqi_hour_date;

          通過尋找id="tempdrday"的text內容,得到AQI實時報的具體日期aqi_day_date;

          3.獲取AQI實時報的城市、AQI和首要污染物

          通過分析網站返回的內容,AQI實時報的具體內容在<table></table>的表格內容了。表體的id="legend_01_table",如下入紅色箭頭所示。

          一個城市一行數據,其結構為<tr><td></td><td></td><td></td></tr>,根據這個特點,編寫代碼如下:

          air_hour_content=soup.find(id='legend_01_table')
          
          tr=air_hour_content.find_all('tr')
          hour_citys=[]
          hour_aqis=[]
          hour_pollutions=[]
          # 獲取AQI實時報的城市、AQI和首要污染物
          for i in range(len(tr)):
              td=tr[i].find_all('td')
              city=td[0].text
              aqi=td[1].text.strip()
              pollution=td[2].text.strip()
              hour_citys.append(city)
              hour_aqis.append(aqi)
              hour_pollutions.append(pollution)

          首先,找到id='legend_01_table'的具體內容,然后find_all尋找所有的tr的內容,接著對每一行的tr的內容,find_all尋找所有的單元格td的內容,最后得到城市:hour_citys、AQI:hour_aqis和首要污染物:hour_pollutions。

          4.獲取AQI日報的城市、AQI和首要污染物

          通過分析網站返回的內容,AQII日報的具體內容在<table></table>的表格內容了。表體的id="legend_02_table",如下入紅色箭頭所示。


          一個城市一行數據,其結構為<tr><td></td><td></td><td></td></tr>,根據這個特點,編寫代碼如下:

          air_day_content=soup.find(id='legend_02_table')
          
          tr=air_day_content.find_all('tr')
          day_citys=[]
          day_aqis=[]
          day_pollutions=[]
          # 獲取AQI日報的城市、AQI和首要污染物
          for i in range(len(tr)):
              td=tr[i].find_all('td')
              city=td[0].text
              aqi=td[1].text.strip()
              pollution=td[2].text.strip()
              day_citys.append(city)
              day_aqis.append(aqi)
              day_pollutions.append(pollution)
          

          首先,找到id='legend_02_table'的具體內容,然后find_all尋找所有的tr的內容,接著對每一行的tr的內容,find_all尋找所有的單元格td的內容,最后得到城市:day_citys、AQI:day_aqis和首要污染物:day_pollutions。

          5、保存解析后的數據

          保存AQI實時報數據,代碼如下:

          file=open('aqi_hour.txt','w',encoding='UTF-8')
          file.write(aqi_hour_date+'\n') 
          file.write('城市,AQI,首要污染物\n')  
          for i in range(len(hour_citys)):
              file.write(hour_citys[i]+','+hour_aqis[i]+','+hour_pollutions[i]+"\n")  
          file.close() 

          AQI實時報數據保存在aqi_hour.txt中。

          保存AQI日報數據,代碼如下:

          file=open('aqi_day.txt','w',encoding='UTF-8')
          file.write(aqi_day_date+'\n') 
          file.write('城市,AQI,首要污染物\n')  
          for i in range(len(day_citys)):
              file.write(day_citys[i]+','+day_aqis[i]+','+day_pollutions[i]+"\n")  
          file.close() 

          AQI日報數據保存在aqi_day.txt中。

          當然,你也可以根據業務場景的需要保存在數據庫中。這里我們就不另外討論了。

          需要說明的是,aqi實時報的網站
          http://datacenter.mee.gov.cn/websjzx/homepages/airDatas.vm,每個小時官方網站更新一次,你如果需要爬取每個小時的數據,就需要每隔一個小時爬取一次就OK了。

          總結:通過網頁調試分析,正確識別提取全國城市空氣質量指數AQI的網址,然后利用requests獲取網頁代碼,接著用bs4進行分析,通過id識別表格內容和發布日期,最后獲取到有用信息后保存到文本文件。



          載鏈接:https://juejin.im/post/5e7e126b51882573c508be13

          背景

          最近在做一個類似支付寶口碑商家的功能模塊,其中有個功能就是計算出用戶與商家的距離,如下圖:


          支付寶口碑商家頁面截圖


          思路分析

          1、商家選取店鋪地址,將坐標經緯度存入數據庫;

          2、移動端定位當前用戶坐標經緯度;

          3、將商家經緯度從數據庫取出與當前用戶經緯度進行計算;

          4、計算出的距離顯示在用戶端;

          用到的工具

          1、HTML5地理定位API;

          2、百度地圖API;

          百度地圖API使用

          1、在百度地圖開放平臺注冊開發者賬號;

          2、登錄開發者賬號,在控制臺中創建應用,如下圖:

          注意:移動web端的話,應用類型記得選擇瀏覽器端


          代碼實現

          1、創建seller.html文件,用來提供商家選取地址坐標經緯度;

          注意:代碼中的ak="您的密鑰",記得換成控制臺中創建應用的AK密鑰


          <!DOCTYPE html>
          <html>
          <head>
              <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
              <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
              <style type="text/css">
                  body, html{
                      width: 100%;
                      height: 100%;
                      margin:0;
                      font-family:"微軟雅黑";
                      font-size:14px;
                  }
                  #l-map{
                      height:300px;
                      width:100%;
                  }
                  #r-result{
                      width:100%;
                  }
              </style>
              <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的密鑰"></script>
              <title>商家選取店鋪地址</title>
          </head>
          <body>
              <div style="display: flex;">
                  <div style="width: 50%;height: 700px" id="l-map"></div>
                  <div style="width: 50%">
                      <div id="r-result">請輸入:<input type="text" id="suggestId" size="20" value="百度" style="width:150px;" /></div>
                      <div id="searchResultPanel" style="border:1px solid #C0C0C0;width:150px;height:auto; display:none;"></div>
                  </div>
              </div>
          
          </body>
          </html>
          <script type="text/javascript">
              // 百度地圖API功能
              function G(id) {
                  return document.getElementById(id);
              }
          
              var map=new BMap.Map("l-map");
              map.centerAndZoom("北京",12);       // 初始化地圖,設置城市和地圖級別。
          
              var ac=new BMap.Autocomplete(    //建立一個自動完成的對象
                  {"input" : "suggestId"
                  ,"location" : map
              });
          
          
              var myValue;
              ac.addEventListener("onconfirm", function(e) {    //鼠標點擊下拉列表后的事件
              var _value=e.item.value;
                  myValue=_value.province +  _value.city +  _value.district +  _value.street +  _value.business;
                  G("searchResultPanel").innerHTML="onconfirm<br />index=" + e.item.index + "<br />myValue=" + myValue;
          
                  setPlace();
              });
          
              function setPlace(){
                  map.clearOverlays();    //清除地圖上所有覆蓋物
                  function myFun(){
                      var pp=local.getResults().getPoi(0).point;    //獲取第一個智能搜索的結果
                      map.centerAndZoom(pp, 18);
                      map.addOverlay(new BMap.Marker(pp));    //添加標注
                  }
                  var local=new BMap.LocalSearch(map, { //智能搜索
                    onSearchComplete: myFun
                  });
                  local.search(myValue);
              }
          
          
              //鼠標單擊獲取點擊的經緯度
              map.addEventListener("click",function(e){
                  alert('該點擊區域的經緯度為:'+e.point.lng + "," + e.point.lat);//將該經緯度存入數據庫中
              });
          
          </script>復制代碼


          seller.html運行效果圖如下:


          2、創建user.html文件,用來定位用戶坐標經緯度,及計算與商家的距離;

          注意1:由于HTML5地理定位僅限在移動端生效,因此user.html需要在移動端下運行(可將文件直接發送到手機上,在手機上打開運行)

          注意2:代碼中的ak="您的密鑰",記得換成控制臺中創建應用的AK密鑰


          <!DOCTYPE html>
          <html>
          <head>
              <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
              <meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
              <script type="text/javascript" src="http://api.map.baidu.com/api?v=2.0&ak=您的密鑰"></script>
              <title>計算用戶到商家的距離</title>
          </head>
          <body>
          
          </body>
          </html>
          <script type="text/javascript">
          
              //使用HTML5地理定位
              function getLocation(){
          
                  //檢測瀏覽器是否支持地理定位
                if (navigator.geolocation){
                      navigator.geolocation.getCurrentPosition(showPosition,showError);
                      //如果getCurrentPosition()運行成功,則向參數showPosition中規定的函數返回一個coordinates對象
                      //getCurrentPosition()方法的第二個參數showError用于處理錯誤。它規定當獲取用戶位置失敗時運行的函數
                  }else{
                      alert("該設備瀏覽器不支持地理定位");
                  }
          
                }
          
          
              function showPosition(position){
          
                  var Longitude=position.coords.longitude;//HTML5定位獲取的經度
                  var Latitude=position.coords.latitude;//HTML5定位獲取的緯度
          
                  //將HTML5定位獲取的經緯度,通過百度地圖API轉換成適應于百度定位的經緯度
                  var ggPoint=new BMap.Point(Longitude,Latitude);
          
                  //坐標轉換完之后的回調函數
                  translateCallback=function (data){
                    if(data.status===0) {
                      var map=new BMap.Map();
                      console.log(data.points[0]);//轉換后新的用戶經緯度
                      var pointA=new BMap.Point(data.points[0].lng,data.points[0].lat);//用戶的經緯度
                      var pointB=new BMap.Point(商家經度,商家緯度);//從數據庫中取出商家的經緯度
                      alert('您到商家的距離是:'+(map.getDistance(pointA,pointB)).toFixed(2)+' 米。');  //獲取兩點距離,保留小數點后兩位
                    }
                  }
          
                  var convertor=new BMap.Convertor();
                  var pointArr=[];
                  pointArr.push(ggPoint);
                  convertor.translate(pointArr, 1, 5, translateCallback)
          
              }
          
              function showError(error){
                switch(error.code) {
                  case error.PERMISSION_DENIED:
                    alert("用戶不允許地理定位")
                    break;
                  case error.POSITION_UNAVAILABLE:
                    alert("無法獲取當前位置")
                    break;
                  case error.TIMEOUT:
                    alert("操作超時")
                    break;
                  case error.UNKNOWN_ERROR:
                    alert("未知錯誤")
                    break;
                  }
                }
          
              getLocation();
          
          </script>復制代碼


          user.html運行效果圖:

          1、初次運行,詢問是否共享位置信息


          2、點擊確認共享位置信息,彈出用戶與商家的距離


          總結

          1、百度地圖API也可定位用戶的坐標經緯度,但是會出現偏移量,與實際位置相差很大,因此可使用HTML5地理定位用戶的原始坐標,再將原始坐標轉換成百度的定位坐標

          2、由于HTML5地理定位僅限在移動端生效,因此使用HTML5地理定位需要在移動端下運行


          最后

          覺得文章不錯的話,給我個關注哇,點個贊唄!

          用場景:百度地圖的應用往往都是在網上的開放式應用,用戶在不同的城市,所以在地圖初始化的時候會希望不同用戶能夠加載自己當地的地圖。

          下面給大家介紹兩種利用百度地圖API,在用戶打開瀏覽器頁面后自動初始化為用戶所在地區地圖的方法

          1. 根據IP定位用戶位置(每一臺連上網路的電腦都具有一個獨一無二的IP位址,經由IP位址可以反查出電腦位置,但是結果并不精確,而且很容易到受到ISP的IP分配機制影響,而造成誤差。本質上,LocalCity這個類是利用用戶IP地址去百度數據庫里查詢得到IP所在的城市。)

            但是代碼非常的簡潔和方便,主要代碼如下:

          <div id="allmap"></div>

          <script type="text/javascript">

          var map=new BMap.Map("allmap");

          var myCity=new BMap.LocalCity();

          myCity.get(myFun);

          function myFun(result){

          var cityName=result.name;

          map.centerAndZoom(cityName,15);

          setTimeout(function(){alert(cityName)},500);

          }

          </script>

          運行效果如下:

          2.Geolocation這個類是使用了支持HTML5瀏覽器提供的Geolocation API 來進行定位的。目前Internet Explorer 9、Firefox、Chrome、Safari 以及 Opera 支持地理定位(因為他們支持HTML5)。

          <div id="allmap"></div>

          <script type="text/javascript">

          var map=new BMap.Map("allmap");

          var point=new BMap.Point(116.331398,39.897445);

          map.centerAndZoom(point,12);

          var geolocation=new BMap.Geolocation(); //實例化瀏覽器定位對象。

          geolocation.getCurrentPosition(function(r){ //定位結果對象會傳遞給r變量

          if(this.getStatus()==BMAP_STATUS_SUCCESS){ //通過Geolocation類的getStatus()判斷定位結果

          var mk=new BMap.Marker(r.point);

          map.addOverlay(mk); //將marker作為覆蓋物添加到map地圖上

          map.panTo(r.point); //移動地圖中心點到當前點

          setTimeout(function(){ alert('您的位 置:'+r.point.lng+','+r.point.lat);},500);

          }

          else {alert('failed'+this.getStatus()); }

          },{enableHighAccuracy: true}) //這個參數的含義就是 是否要求瀏覽器獲取最佳定位結果。

          </script>

          運行效果如下:

          以上兩種方法大家可以根據自己的實際情況來使用,有問題也可以留言討論


          主站蜘蛛池模板: 精品一区二区三区四区| 色婷婷综合久久久久中文一区二区| 免费无码A片一区二三区| 亚洲日本久久一区二区va| 亚洲熟女综合色一区二区三区| 天堂Av无码Av一区二区三区| 国产亚洲综合一区二区三区| 亚洲国产成人久久综合一区77 | 日韩毛片基地一区二区三区| 亚洲av日韩综合一区二区三区| 国产中文字幕一区| 国产日韩一区二区三区在线观看| 精品无码一区二区三区爱欲九九| 在线观看精品视频一区二区三区| 久久精品国产亚洲一区二区三区| 精品女同一区二区三区免费站| 波多野结衣一区二区三区88| 精品久久一区二区| 国产一区二区在线观看视频| 国产色情一区二区三区在线播放| 亚洲Av永久无码精品一区二区 | 国内自拍视频一区二区三区| 免费在线视频一区| 免费无码VA一区二区三区| 久久久久人妻精品一区三寸| 中文字幕在线观看一区| 无码中文字幕乱码一区| 日本一区二区三区高清| 欧美日韩综合一区二区三区| 国产精品一区二区av| 国产成人一区二区三区高清| 少妇特黄A一区二区三区| 一区二区三区免费高清视频| 无码播放一区二区三区| 亚洲日韩精品一区二区三区| 日韩成人一区ftp在线播放| 99精品一区二区三区| 国产在线精品一区二区夜色| 婷婷亚洲综合一区二区| 无码国产精品一区二区免费式影视 | 日韩一区二区三区在线精品|