1.作業①
1.1作業内容
要求:用urllib和re庫方法定向爬取給定網址(https://www.shanghairanking.cn/rankings/bcsr/2020/0812)的資料。
輸出資訊:
![]()
資料采集 實驗一
1.2解題思路
1.2.1擷取頁面資訊
import urllib.request
import re
url ="https://www.shanghairanking.cn/rankings/bcsr/2020/0812"
page=urllib.request.urlopen(url)
html = page.read().decode('utf-8')
使用urllib.request.urlopen發送請求,不設定請求頭依然可以正常通路。
page.read()擷取該網站的html資訊。
.decode('utf-8') 設定編碼方式為utf-8。
1.2.2解析頁面
在浏覽器檢視:
可以看到需要爬取的資訊都直接寫在html檔案内,隻要使用正則比對出想要的内容就可以了。
regrank1 ='<div class="ranking" .+\n.+' #正規表達式-排名
regrate ='0ae>\n.+\n +<!' #正規表達式-層次
regname='class="name-cn".+ </a>' #正規表達式—學校名稱
regpoint='</div></td><td data-v-68e330ae>\n.+' #正規表達式-總分
rank2020=[] #用于存儲排名清單
rates=[] #用于存儲前百分數
names=[] #存儲學校名稱
points=[] #存儲總分
編寫正規表達式并建立存儲的清單
逐一比對并去除多餘的内容:
rank1 = re.findall(regrank1,html)
for i in rank1:
rank2020.append(i[-2:])
rate = re.findall(regrate,html)
for i in rate:
i=i.replace(" ","").replace("\n","")
rates.append(i[4:-2])
name=re.findall(regname,html)
for i in name:
names.append(i[32:-4])
point=re.findall(regpoint,html)
for i in point:
i=i.replace(" ","").replace("\n","")
points.append(i[30:])
1.2.3輸出
使用.format來格式化輸出的内容:
print("{0:{4}<5}\t{1:{4}<12}\t{2:{4}<9}\t{3:{4}<5}".format("排名","全部層次","學校名稱","總分",chr(12288))) #輸出
for i in range(len(names)):
print("{0:{4}<5}\t{1:{4}<12}\t{2:{4}<9}\t{3:{4}<5}".format(rank2020[i],rates[i],names[i],points[i],chr(12288)))
結果:
1.3心得體會
1.在輸出爬取的内容時,需要使用.format來使輸出更加整齊直覺,使用中文的空格(chr(12288))可以防止中英文數字等無法對其
2.爬取頁面時,可以先将整個頁面的html存儲到本地以防止短時間内過多通路Ip被封
2.作業②
2.1作業内容
– 要求:用requests和Beautiful Soup庫方法設計爬取https://datacenter.mee.gov.cn/aqiweb2/ AQI實時報。
– 輸出資訊:
2.2解題思路
2.2.1擷取頁面資訊
首先也是發送請求擷取頁面資訊:
import requests
from bs4 import BeautifulSoup
url = "https://datacenter.mee.gov.cn/aqiweb2/"
reponse = requests.get(url=url)
bs4 = BeautifulSoup(reponse.text, 'lxml')
使用requests發送請求并用BeautifulSoup解析擷取的頁面資訊,此次作業的網站不用設定請求頭也可正常爬取。
2.2.2頁面資訊的處理
在浏覽器檢視所需爬取的資訊:
可以看到需要爬取的資訊都在td标簽的清單中,是以直接查找所有td标簽就可以了
pages = bs4.find_all('td')
顯示所有查找到的内容可以發現:
所需要的資訊是9歌一循環的,我們需要其中的7個資訊
除了需要的資訊以外還有一些空格換行等轉義符
初次之外要求爬取的是AQI實時報,但是把AQI日報的内容也輸出了
所有我們要去除這部分的資訊
先建立了清單citys,sqi,pm25,so2,no2,co,maxs來存儲對應的資訊
count = 1
mark1 = 0 # 用于标記Aqi實時報是否爬取結束
for i in pages:
text = i.text.replace(" ", "").replace("\n", "").replace("\t", "").replace("\r", "") #替換掉空格換行等符号
switch = count % 9
if switch == 1:
citys.append(text)
if text == "北京市": #用于判斷aqi實時報是否結束
mark1 += 1
if mark1 == 2: # aqi是時報爬取結束,接下去是aqi日報,不爬取
break
elif switch == 2: # aqi的值
aqi.append(text)
elif switch == 3: # pm2.5值
pm25.append(text)
elif switch == 5: # so2的值
so2.append(text)
elif switch == 6: # no2
no2.append(text)
elif switch == 7: # co
co.append(text)
elif switch == 0: # 首要污染物
maxs.append(text)
count += 1
同時使用mark1來判斷AQI實時報的内容是否讀取結束進去AQI日報,第二次出現“北京市”是就結束循環
2.2.3輸出
print("{:{opt}<10}\t{:{opt}<10}\t{:{opt}<10}\t{:{opt}<11}\t{:{opt}<10}\t{:{opt}<10}\t{:{opt}<10}\t{:{opt}<10}".format("序号", "城市", "AQI", "PM2.5", "SO2", "No2", "Co", "首要污染物", opt=chr(12288)))
for i in range(len(aqi)):
print("{:{opt}<10}\t{:{opt}<10}\t{:{opt}<10}\t{:{opt}<10}\t{:{opt}<10}\t{:{opt}<10}\t{:{opt}<10}\t{:{opt}<10}".format(i + 1, citys[i], aqi[i], pm25[i], so2[i], no2[i], co[i], maxs[i], opt=chr(12288)))
2.3心得體會
在爬取頁面内容時,要主要爬取的資訊是否全部為所需要的,防止在其他操作時出現意外狀況,如本題的AQI實時報和AQI日報,剛開始将AQI日報的内容也一并存入清單,使輸出時出現報錯,浪費了不少時間
3.作業③
3.1作業内容
– 要求:使用urllib和requests和re爬取一個給定網頁(https://news.fzu.edu.cn/)爬取該網站下的所有圖檔
– 輸出資訊:将自選網頁内的所有jpg檔案儲存在一個檔案夾中
3.2解題思路
3.2.1擷取頁面資訊
題目要求使用urllib和requests,應該是兩個用一個就行吧
import requests
import re
import matplotlib.pyplot as plt
import urllib
url ="http://news.fzu.edu.cn/"
reponse = requests.get(url=url) #requests
#reponse = urllib.request.urlopen(url) #urllib
page=reponse.text #requests
# page = reponse.read().decode('utf-8') #urllib
3.2.2解析頁面内容
可以看到網頁的圖檔都存儲的img标簽中,其中有jpg圖檔和gif圖檔
3.2.3爬取圖檔思路
網頁中的圖檔在img标簽中以以源位址的形式存儲,打開該位址可以看到:
我們需要擷取這個位址然後以二進制寫入檔案中就可以實作下載下傳
reg ="<img src=.+jpg" #查找Jpg格式的圖檔# reg = "<img src=.+gif" #擷取gif格式的圖檔name = re.findall(reg,page)imgsrcs=[] #存儲圖檔srcfor i in name: imgsrcs.append(url+i[11:])
寫入檔案:
for i in range(len(imgsrcs)): pic = imgsrcs[i] # 加上https: with open("./imgs/"+str(i)+ '.jpg', 'wb') as imgs: # 将圖檔寫進圖檔檔案 pic2 = requests.get(pic).content # 擷取圖檔連結的二進制 imgs.write(pic2) # 把圖檔的二進制寫進圖檔檔案
結果: