開發小案例-綜合運用
學習了這么多知識,這節課我們來實踐一下,我們在這節課會設計一個小爬蟲來爬取慕課網所有的免費課信息。當然,爬取慕課網所有免費課信息只是一個大的目標而已,具體要實現這個目標我們還需要對劃分步驟,將一個大目標分解成一個個的小目標才可以。在實際的開發工作中我們也需要這樣,拿到需求之后不要上來就開始寫代碼,然后一邊寫一邊運行調試,雖然這樣不能說錯吧,但是卻跟裝運氣一樣,試對了就對了,錯了還一直在哪里糾結。下面我們先來看下這個小爬蟲的案例步驟:
1. 案例步驟與目標:
- 分析網站
- 書寫程序
- 運行程序,并將結果存入MongoDB
1.1 目標:
通過本案例,學習BeautifulSoup的網站分析方法,以及掌握將數據存入MongoDB
1.2 分析網站
第一步,打開慕課網網址,然后點擊免費課程,效果如下:
接下來,我們右鍵單擊鼠標,效果如下:
點擊 Inspect 后,在瀏覽器的下端,會彈出瀏覽器 debug 控制面板:
單擊左上角的小三角,然后選定一個課程,效果如下:
如下圖陰影部分所示,是圖片的在 html 中的位置,我們需要整個課程的信息,因此提取 course-card-content 作為基本模塊:
在程序里,我們需要使用 BeautifulSoup 定位到到這里。
2. 書寫程序
我們先來看一下代碼的架構:
接下來,讓我們看看所有代碼。
import requests
from bs4 import BeautifulSoup
from pprint import pprint
import os
import lxml
import pymongo
headers = {'User-Agent' : 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.79 Safari/537.36'} # 請求頭部
def get_course_info():
""" get all course basic unit """
url = "http://www.xianlaiwan.cn/course/list" #慕課網免費課地址
r = requests.get(url, headers= headers) # 發送請求
bs = BeautifulSoup(r.text, "lxml") # 解析網頁
course_data = bs.find_all("div", class_="course-card-container") # 定位課程信息
return course_data
def save_pics(course_data):
""" save pics from imooc free course """
for each_item in course_data:
img = each_item.find("img")
image_link = img.attrs["data-original"].split("/")
image_address = "http:" + img.attrs["data-original"]
with open(image_link[-1],'wb+') as f:
res = requests.get(image_address, headers= headers) # 發送請求
f.write(res.content)
def save_courses_to_mongodb(mongod_con, course_data):
""" save info to mongodb """
for each_item in course_data:
imgs = each_item.find("img")
desc = each_item.find("p", class_="course-card-desc") # 定位課程信息
class_name = each_item.find("h3", class_="course-card-name") # 定位課程信息
imooc_dict = { "class_name": class_name.getText(), "class_pics": imgs.attrs["data-original"], "people":desc.getText()}
x = mongod_con.insert_one(imooc_dict)
def create_local_pic_dir():
""" if don't have local dir, create one for holding the pics which download from the imooc. """
directory = os.path.dirname(os.path.realpath(__file__)) + '/imooc_pics/'
if not os.path.exists(directory):
os.makedirs(directory)
os.chdir(directory)
def db_connectin():
""" Connection to local mongo db service."""
try:
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
mydb = myclient["practice"]
mongod_con = mydb["imooc_courses"]
except Exception as e:
print("ERROR(MongoPipeline):", e)
return mongod_con
def main():
""" This is the main entry for running code."""
create_local_pic_dir()
mycol = db_connectin()
data = get_course_info()
if data:
save_pics(data)
save_courses_to_mongodb(mycol, data)
if __name__ == "__main__":
main()
代碼主要有 6 個函數:
- create_local_pic_dir: 用來創建本地文件夾,來存儲爬取的圖片;
- db_connectin: 用來連接 mongodb;
- get_course_info :用來獲取課程基本信息;
- save_pics :函數將圖片存儲在本地;
- save_courses_to_mongodb :將數據存儲到 MongoDB;
- main :負責運行程序。
2.1 create_local_pic_dir
首先,在本地創建一個文件夾,來存儲從慕課網下載下來的圖片信息。
2.2 db_connectin
建立本地的連接,并返回一個連接句柄。
2.3 get_course_info
通過前面網站的分析,我們可以通過調用 bs4 的 find_all() 方法來定位課程的基本單元,然后通過遍歷,獲取課程的詳細信息。
2.4 save_pics
在存儲圖片的時候,我們需要提取圖片的名稱,使用 split 將網址分開,然后取倒數第一數據,就是圖片的名稱。
2.5 save_courses_to_mongodb
在我們成功連接 mongdb 之后,通過調用 insert_one() 方法,我們可以把課程的字典信息,一條一條的存儲到 mongodb 中。
2.6 運行程序,并將結果存入MongoDB
可以看到,程序創建了 imooc_pics 文件夾,里面存儲了我們從慕課網下載的免費課程的介紹圖片。
打開一張圖片可以看到是一張課程的封面圖:
最后,我們使用 MongoDB 的可視化工具,看一下圖片的存儲情況,效果如下圖所示:
3. 小結
這一小節,我們通過實際的案例,熟悉了網址的分析,數據的存儲,以及圖片的存儲。通過整個案例,我們需要掌握 BeautifulSoup 的用法,以及 mongoDB 數據存儲的使用。掌握了這個完整的案例,同學們可以舉一反三,可以使用相同的步驟輕松爬取的許多類似的網站。