數據采集與融合技術作業一
數據采集與融合技術作業一
??1.相關信息及鏈接
| 名稱 | 信息及鏈接 |
|---|---|
| 學號姓名 | 102202108 王露潔 |
| 本次作業要求鏈接 | https://edu.cnblogs.com/campus/fzu/2024DataCollectionandFusiontechnology/homework/13286 |
| 作業①所在碼云鏈接 | https://gitee.com/wanglujieeee/crawl_project/tree/master/作業1.1 |
| 作業②所在碼云鏈接 | https://gitee.com/wanglujieeee/crawl_project/tree/master/作業1.2 |
| 作業③所在碼云鏈接 | https://gitee.com/wanglujieeee/crawl_project/tree/master/作業1.3 |
??2.作業內容
作業①:
??要求:用requests和BeautifulSoup庫方法定向爬取給定網址(http://www.shanghairanking.cn/rankings/bcur/2020)的數據,屏幕打印爬取的大學排名信息。
??輸出信息:
| 排名 | 學校名稱 | 省市 | 學校類型 | 總分 |
|---|---|---|---|---|
| 1 | 清華大學 | 北京 | 綜合 | 852.5 |
| ... |
??代碼實現(詳細注釋版)
import requests # 導入requests庫,用于發送HTTP請求
from bs4 import BeautifulSoup # 導入BeautifulSoup庫,用于解析HTML文檔
import pandas as pd # 導入pandas庫,用于數據處理和生成DataFrame
# 目標URL,即我們要抓取的網頁地址
url = "http://www.shanghairanking.cn/rankings/bcur/2020"
try:
# 發送HTTP GET請求到目標URL
resp = requests.get(url)
# 檢查請求是否成功,如果失敗則拋出HTTPError異常
resp.raise_for_status()
# 獲取網頁的HTML內容
html = resp.content
# 使用BeautifulSoup解析HTML文檔,'lxml'是解析器
soup = BeautifulSoup(html, 'lxml')
# 查找網頁中的排名表格,這里假設表格的<table>標簽是唯一的,實際情況可能需要根據HTML結構修改選擇器
ranking_table = soup.find('table')
# 如果找到了排名表格
if ranking_table:
# 查找表格中的所有行<tr>
rows = ranking_table.find_all('tr')
# 初始化一個空列表,用于存儲每行的數據
list_of_rows = []
# 遍歷每一行
for row in rows:
# 查找行中的所有單元格<td>(這里排除了<th>,因為表格頭部通常不包含我們需要的數據)
cells = row.find_all(['td'])
# 初始化一個空列表,用于存儲當前行的數據
row_data = []
# 遍歷當前行的每個單元格
for i, cell in enumerate(cells, start=1):
# 如果當前單元格是第二列(即學校中文名稱),則特殊處理
if i == 2:
# 在單元格中查找class為"name-cn"的元素,這通常是學校中文名稱的容器
cell = cell.find(class_="name-cn")
# 如果找到了,則將其文本內容(去除前后空白)添加到行數據中
if cell:
row_data.append(cell.text.strip())
# 如果當前單元格是第六列(我們不需要的列,比如操作按鈕等),則停止繼續處理當前行的剩余單元格
elif i == 6:
break
# 對于其他單元格,直接將其文本內容(去除前后空白)添加到行數據中
else:
row_data.append(cell.text.strip())
# 如果當前行有數據(即非空行),則將其添加到列表中
if row_data:
list_of_rows.append(row_data)
# 使用pandas庫將列表轉換為DataFrame,并指定列名
df = pd.DataFrame(list_of_rows, columns=['排名', '學校名稱', '省市', '學校類型', '總分'])
# 打印DataFrame
print(df)
else:
# 如果沒有找到排名表格,則打印提示信息
print('未找到排名表格。')
except requests.exceptions.RequestException as e:
# 捕獲requests庫拋出的異常,并打印錯誤信息
print(f'無法打開網址:{url},錯誤:{e}')
except Exception as e:
# 捕獲其他所有異常,并打印錯誤信息
print(f'發生錯誤:{e}')
??運行結果截圖


??心得體會
在深入學習和實踐這段代碼后,我深刻感受到編程的魅力與挑戰并存。代碼不僅僅是實現功能的工具,更是一種嚴謹的邏輯思考和問題解決能力的體現。通過不斷調試和優化,我學會了如何更有效地利用requests和BeautifulSoup庫來抓取和解析網頁數據,同時也掌握了使用pandas處理和分析數據的基本技巧。這個過程不僅鍛煉了我的技術實力,更讓我明白,編程需要細心、耐心和不斷的學習。每一次成功抓取到數據,都讓我對編程有了更深的理解和熱愛。
作業②:
??要求:用requests和re庫方法設計某個商城(自已選擇)商品比價定向爬蟲,爬取該商城,以關鍵詞“書包”搜索頁面的數據,爬取商品名稱和價格。
??輸出信息:
| 序號 | 價格 | 商品名稱 |
|---|---|---|
| 1 | 65.00 | xxx |
| ... |
??代碼實現
# 導入必要的庫
from bs4 import BeautifulSoup # 用于解析HTML文檔
from bs4.dammit import UnicodeDammit # 用于處理字符編碼問題
import requests # 用于發送HTTP請求
import pandas as pd # 用于數據處理和生成DataFrame
# 目標URL,即我們要抓取的當當網搜索頁面地址(已進行URL編碼)
url = "http://search.dangdang.com/?key=%CA%E9%B0%FC&act=input"
try:
# 設置HTTP請求頭,模擬瀏覽器訪問,避免被網站反爬蟲機制識別為爬蟲
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36"
}
# 發送HTTP GET請求到目標URL,并帶上請求頭
data = requests.get(url, headers=headers)
# 檢查請求是否成功,如果失敗則拋出HTTPError異常
data.raise_for_status()
# 獲取網頁的原始內容(字節碼)
raw_content = data.content
# 使用UnicodeDammit處理字符編碼問題,嘗試使用utf-8和gbk編碼,選擇最合適的編碼方式
dammit = UnicodeDammit(raw_content, ["utf-8", "gbk"])
# 獲取處理后的Unicode字符串(即HTML文檔)
html_content = dammit.unicode_markup
# 使用BeautifulSoup解析HTML文檔,'lxml'是解析器
soup = BeautifulSoup(html_content, "lxml")
# 使用CSS選擇器查找所有匹配的<li>元素,這些元素位于class為'bigimg'的<ul>下
# 注意:這里的選擇器需要根據網頁的實際結構進行調整
lis = soup.select("ul.bigimg li")
# 初始化一個空列表,用于存儲每個商品的數據
products_data = []
# 遍歷每個<li>元素(即每個商品)
for li in lis:
try:
# 初始化一個空列表,用于存儲當前商品的數據
current_product_data = []
# 使用CSS選擇器查找商品名稱的<a>標簽,并獲取其title屬性(商品名稱)
# 注意:如果<a>標簽不存在或沒有title屬性,將返回空字符串
name_tag = li.select_one("p.name a")
name = name_tag.get('title', '') if name_tag else ''
# 使用CSS選擇器查找商品價格,并獲取其文本內容(去除前后空白)
# 注意:如果價格標簽不存在,將返回空字符串
price_tag = li.select_one("span.price_n")
price = price_tag.text.strip() if price_tag else ''
# 將商品名稱和價格添加到當前商品的數據列表中
current_product_data.append(name)
current_product_data.append(price)
# 將當前商品的數據列表添加到總列表中
products_data.append(current_product_data)
except Exception as err:
# 如果在處理某個商品時發生異常,則打印錯誤信息,并繼續處理下一個商品
print(f"Error processing item: {err}")
# 使用pandas庫將總列表轉換為DataFrame,并指定列名
df = pd.DataFrame(products_data, columns=['商品名稱', '價格'])
# 調整DataFrame中列的順序,將'價格'列放在前面,'商品名稱'列放在后面
df = df[['價格', '商品名稱']]
# 打印DataFrame,查看抓取到的商品數據
print(df)
except Exception as err:
# 如果在請求網頁或處理數據時發生異常,則打印錯誤信息
print(f"An error occurred: {err}")
??運行結果截圖(部分)

??心得體會
在編寫和調試上述代碼的過程中,我深刻體會到了幾個關鍵點。首先,數據的抓取和解析需要耐心和細致,因為網頁的結構往往復雜多變,選擇器必須精確無誤。其次,編碼問題在實際開發中是一個常見的陷阱,使用UnicodeDammit這樣的工具能夠大大簡化這一過程。再者,異常處理對于確保程序的健壯性至關重要,它可以幫助我們捕捉并處理潛在的錯誤,避免程序崩潰。最后,Pandas庫在處理表格數據時表現出色,其強大的功能使得數據整理和分析變得更加簡單高效。這次經歷不僅提升了我的編程技能,也讓我對Web開發和數據處理有了更深入的理解。
作業③:
??要求:爬取一個給定網頁([https://news.fzu.edu.cn/yxfd.htm]))或者自選網頁的所有JPEG和JPG格式文件,并將這些文件保存在一個指定的文件夾中。
??輸出信息:將自選網頁內的所有JPEG和JPG文件保存在一個文件夾中,文件夾中包含所有下載的圖片文件。
??代碼實現
自選網頁:https://search.dangdang.com/?key=???????&act=input&show=big&show_shop=0#J_tab
注意:查看過后發現該網頁只有jps格式的圖片,所以代碼中體現的是只爬取了jps格式的圖片
import requests # 導入requests庫,用于發送HTTP請求
import re # 導入re庫,用于正則表達式匹配
import os # 導入os庫,用于文件和目錄操作
# 定義當當網搜索頁面的基礎URL(已進行URL編碼)
base_url = f"https://search.dangdang.com/?key=%D3%A2%D3%EF%C2%FE%BB%AD&act=input&show=big&show_shop=0#J_tab"
# 設置HTTP請求頭,模擬瀏覽器訪問,避免被網站反爬蟲機制識別為爬蟲
headers = {"User-Agent": "Mozilla/5.0(Windows;U;Windows NT 6.0 x64;en-US;rv:1.9pre)Gecko/2008072421 Minefield/3.0.2pre"}
# 檢查是否存在名為"images"的目錄,如果不存在則創建該目錄
if not os.path.exists("images"):
os.makedirs("images")
def fetch_images(url):
"""
發送HTTP GET請求到指定URL,并返回響應的HTML內容。
如果請求失敗,則打印錯誤信息并返回None。
"""
resp = requests.get(url, headers=headers)
if resp.status_code == 200:
return resp.text
else:
print(f"Failed to fetch page: {url}")
return None
def parse_images(html):
"""
使用正則表達式從HTML內容中提取圖片URL。
匹配以'src='或'data-original='開頭,并以'.jpg'結尾的URL。
返回提取到的圖片URL列表。
"""
# 注意:這里的正則表達式可能需要根據網頁的實際結構進行調整
image_tuples = re.findall(r'(src|data-original)=["\'](//.*?\.jpg)["\']', html) # 匹配以//開頭的URL
image_urls = [img[1] for img in image_tuples]
return image_urls
def save_images(image_urls):
"""
遍歷圖片URL列表,下載圖片并保存到本地"images"目錄中。
圖片文件名以"image_序號.jpg"的格式命名。
如果下載過程中發生異常,則打印錯誤信息。
"""
for idx, img_url in enumerate(image_urls):
# 如果URL以//開頭,則補充為完整的http或https URL(這里默認使用http)
if img_url.startswith('//'):
img_url = 'http:' + img_url
try:
# 發送HTTP GET請求到圖片URL,并設置stream=True以流式方式下載圖片
img_response = requests.get(img_url, stream=True)
img_response.raise_for_status() # 確保請求成功
# 構造圖片文件名
img_name = os.path.join("images", f"image_{idx + 1}.jpg")
# 以二進制寫入方式打開文件,并將圖片內容寫入文件
with open(img_name, "wb") as img_file:
img_file.write(img_response.content)
print(f"Saved: {img_name}")
except Exception as e:
# 如果下載過程中發生異常,則打印錯誤信息
print(f"Could not save image {img_url}: {e}")
def main():
"""
主函數,用于執行整個圖片抓取流程。
1. 從當當網搜索頁面抓取HTML內容。
2. 解析HTML內容,提取圖片URL。
3. 下載并保存前20張圖片到本地。
"""
html_content = fetch_images(base_url)
if html_content:
image_urls = parse_images(html_content)
# 限制只爬取前20個圖片(注意:原代碼中寫的是[:20],但注釋寫的是前100個,這里以代碼為準)
save_images(image_urls[:20])
if __name__ == "__main__":
# 當腳本被直接運行時,調用main函數
main()
??運行結果截圖


??心得體會
通過編寫這段代碼,我掌握了如何使用Python進行網頁內容抓取、解析以及圖片下載的基本流程。首先,我學習了如何利用requests庫模擬HTTP請求,并設置合適的請求頭以繞過一些簡單的反爬蟲機制。其次,我了解到re模塊在文本處理中的強大功能,通過正則表達式可以高效地提取出所需的信息,如圖片URL。此外,我還學會了使用os模塊進行文件操作,如創建目錄和保存文件。在下載圖片時,我意識到需要處理各種可能的異常情況,如網絡請求失敗或文件寫入錯誤,這促使我更加深入地理解了異常處理的重要性。最后,通過限制爬取的圖片數量,我學會了如何在抓取數據時保持禮貌,避免對目標網站造成過大的負擔。這次實踐不僅增強了我的編程技能,也讓我對Web數據抓取有了更深入的理解。

浙公網安備 33010602011771號