網站,:豆瓣電影 Top 250
爬取豆瓣前250電影的信息,?
F12打開網頁控制臺,查看網頁元素,
?發現網頁數據直接可以查看到,為靜態網頁數據,較為簡單
目錄
1.第一步使用urllib庫獲取網頁
2.第二步使用BeautifulSoup和re庫解析數據
2.1.定位數據塊
?2.2.正則化匹配
3.第三步數據導出excel
完整代碼:
1.第一步使用urllib庫獲取網頁
觀察網頁url結構:
?首先,我們分析一下這個網頁的結構,是一個還算比較規則的網頁,每頁25條,一共10頁。
? ? 我們點擊第一頁:url = https://movie.douban.com/top250?start=0&filter=
? ? 我們點擊第二頁:url = 豆瓣電影 Top 250
? ? 我們點擊第三頁:url = 豆瓣電影 Top 250
import urllib.request, urllib.error# 定義基礎url,發現規律,每頁最后變動的是start=后面的數字
baseurl = "https://movie.douban.com/top250?start="# 定義一個函數getHtmlByURL,得到指定url網頁的內容
def geturl(url):# 自定義headers(偽裝,告訴豆瓣服務器,我們是什么類型的機器,以免被反爬蟲)headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'}# 利用Request類來構造自定義頭的請求req = urllib.request.Request(url, headers=headers)# 定義一個接收變量,用于接收html = ""try:# urlopen()方法的參數,發送給服務器并接收響應resp = urllib.request.urlopen(req)# urlopen()獲取頁面內容,返回的數據格式為bytes類型,需要decode()解碼,轉換成str類型html = resp.read().decode("utf-8")except urllib.error.URLError as e:if hasattr(e, "code"):print(e.code)if hasattr(e, "reason"):print(e.reason)return htmlprint(geturl(baseurl + "0"))
2.第二步使用BeautifulSoup和re庫解析數據
2.1.定位數據塊
?需要找到我們需要的信息在對應數據中的那個位置里面,可以在控制臺定位,
我們需要獲取的數據標簽是 ‘div’,類名是‘item’,
from bs4 import BeautifulSoup# 定義一個函數,并解析這個網頁
def analysisData(url):# 獲取指定網頁html = geturl(url)# 指定解析器解析html,得到BeautifulSoup對象soup = BeautifulSoup(html, "html5lib")# 定位我們的數據塊在哪for item in soup.find_all('div', class_="item"):print(item)return ""analysisData(baseurl)
2.2.正則化匹配
現在獲取到的塊還是原始的css代碼,創建正則化匹配篩選出我們需要的數據,
- 提取詳細鏈接:
?findLink = re.compile(r'<a href="(.*?)">')
- ?圖片
?findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S)
- ?片名
findTitle = re.compile(r'<span class="title">(.*)</span>')
import re# 定義正則對象獲取指定的內容
# 提取鏈接(鏈接的格式都是<a href="開頭的)
findLink = re.compile(r'<a href="(.*?)">')
# 提取圖片
findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S) # re.S讓 '.' 特殊字符匹配任何字符,包括換行符;
# 提取影片名稱
findTitle = re.compile(r'<span class="title">(.*)</span>')
# 提取影片評分
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
# 提取評價人數
findJudge = re.compile(r'<span>(\d*)人評價</span>')
# 提取簡介
inq= re.compile(r'<p\s+class="quote">.*?<span>(.*?)</span>.*?</p>', re.S)
# 提取相關內容
findBd = re.compile(r'<div class="bd">\s*<p>\s*'r'導演: (.*?)\s*主演: (.*?)<br/>\s*'r'(\d{4}).*?/\s*(.*?)\s*/\s*(.*?)\s*</p>',re.S
)# 定義一個函數,并解析這個網頁
def analysisData(baseurl):# 獲取指定網頁html = geturl(baseurl)# 指定解析器解析html,得到BeautifulSoup對象soup = BeautifulSoup(html, "html5lib")dataList = []# 定位我們的數據塊在哪for item in soup.find_all('div', class_="item"):# item 是 bs4.element.Tag 對象,這里將其轉換成字符串來處理item = str(item)# 定義一個列表 來存儲每一個電影解析的內容data = []# findall返回的是一個列表,這里提取鏈接link = re.findall(findLink, item)[0]data.append(link) # 添加鏈接img = re.findall(findImgSrc, item)[0]data.append(img) # 添加圖片鏈接title = re.findall(findTitle, item)# 一般都有一個中文名 一個外文名if len(title) == 2:# ['肖申克的救贖', '\xa0/\xa0The Shawshank Redemption']titlename = title[0] + title[1].replace(u'\xa0', '')else:titlename = title[0] + ""data.append(titlename) # 添加標題pf = re.findall(findRating, item)[0]data.append(pf)pjrs = re.findall(findJudge, item)[0]data.append(pjrs)# 有的可能沒有inqInfo = re.findall(inq, item)if len(inqInfo) == 0:data.append(" ")else:data.append(inqInfo[0])matches = re.findall(findBd, item)if matches: # 確保列表非空bd = matches[0]else:bd = None # 或設定默認值/拋出異常# [('\n 導演: 弗蘭克·德拉邦特 Frank Darabont\xa0\xa0\xa0主演: 蒂姆·羅賓斯 Tim Robbins /...<br/>\n 1994\xa0/\xa0美國\xa0/\xa0犯罪 劇情\n ', '\n\n \n ')]# bd[0].replace(u'\xa0', '').replace('<br/>', '')# bd = re.sub('<\\s*b\\s*r\\s*/\\s*>', "", bd[0])# bd = re.sub('(\\s+)?', '', bd)data.append(bd)dataList.append(data)return dataListprint(analysisData(baseurl))
3.第三步數據導出excel
因為處理的是一個頁面的,所以需要寫一個循環,
import xlwtdef main():allData = []for i in range(0, 250, 25):url = baseurl + str(i)dataList = analysisData(url)allData.extend(dataList)savepath = "C:\pythonProject\python爬蟲\爬取豆瓣電影\豆瓣250.xls"book = xlwt.Workbook(encoding="utf-8", style_compression=0) # 創建Workbook對象sheet = book.add_sheet("豆瓣電影Top250", cell_overwrite_ok=True) # 創建工作表col = ("電影詳情鏈接", "圖片鏈接", "電影中/外文名", "評分", "評論人數", "概況", "相關信息")print(len(allData))for i in range(0, 7):sheet.write(0, i, col[i])for i in range(0, 250):print('正在保存第'+str((i+1))+'條')data = allData[i]for j in range(len(data)):sheet.write(i + 1, j, data[j])book.save(savepath)if __name__ == '__main__':main()
完整代碼:
import urllib.request, urllib.error# 定義基礎url,發現規律,每頁最后變動的是start=后面的數字
baseurl = "https://movie.douban.com/top250?start="# 定義一個函數getHtmlByURL,得到指定url網頁的內容
def geturl(url):# 自定義headers(偽裝,告訴豆瓣服務器,我們是什么類型的機器,以免被反爬蟲)headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'}# 利用Request類來構造自定義頭的請求req = urllib.request.Request(url, headers=headers)# 定義一個接收變量,用于接收html = ""try:# urlopen()方法的參數,發送給服務器并接收響應resp = urllib.request.urlopen(req)# urlopen()獲取頁面內容,返回的數據格式為bytes類型,需要decode()解碼,轉換成str類型html = resp.read().decode("utf-8")except urllib.error.URLError as e:if hasattr(e, "code"):print(e.code)if hasattr(e, "reason"):print(e.reason)return htmlfrom bs4 import BeautifulSoup# 定義一個函數,并解析這個網頁
def analysisData(url):# 獲取指定網頁html = geturl(url)# 指定解析器解析html,得到BeautifulSoup對象soup = BeautifulSoup(html, "html5lib")# 定位我們的數據塊在哪for item in soup.find_all('div', class_="item"):print(item)return ""analysisData(baseurl)
import re# 定義正則對象獲取指定的內容
# 提取鏈接(鏈接的格式都是<a href="開頭的)
findLink = re.compile(r'<a href="(.*?)">')
# 提取圖片
findImgSrc = re.compile(r'<img.*src="(.*?)"', re.S) # re.S讓 '.' 特殊字符匹配任何字符,包括換行符;
# 提取影片名稱
findTitle = re.compile(r'<span class="title">(.*)</span>')
# 提取影片評分
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
# 提取評價人數
findJudge = re.compile(r'<span>(\d*)人評價</span>')
# 提取簡介
inq= re.compile(r'<p\s+class="quote">.*?<span>(.*?)</span>.*?</p>', re.S)
# 提取相關內容
findBd = re.compile(r'<div class="bd">\s*<p>\s*'r'導演: (.*?)\s*主演: (.*?)<br/>\s*'r'(\d{4}).*?/\s*(.*?)\s*/\s*(.*?)\s*</p>',re.S
)# 定義一個函數,并解析這個網頁
def analysisData(baseurl):# 獲取指定網頁html = geturl(baseurl)# 指定解析器解析html,得到BeautifulSoup對象soup = BeautifulSoup(html, "html5lib")dataList = []# 定位我們的數據塊在哪for item in soup.find_all('div', class_="item"):# item 是 bs4.element.Tag 對象,這里將其轉換成字符串來處理item = str(item)# 定義一個列表 來存儲每一個電影解析的內容data = []# findall返回的是一個列表,這里提取鏈接link = re.findall(findLink, item)[0]data.append(link) # 添加鏈接img = re.findall(findImgSrc, item)[0]data.append(img) # 添加圖片鏈接title = re.findall(findTitle, item)# 一般都有一個中文名 一個外文名if len(title) == 2:# ['肖申克的救贖', '\xa0/\xa0The Shawshank Redemption']titlename = title[0] + title[1].replace(u'\xa0', '')else:titlename = title[0] + ""data.append(titlename) # 添加標題pf = re.findall(findRating, item)[0]data.append(pf)pjrs = re.findall(findJudge, item)[0]data.append(pjrs)# 有的可能沒有inqInfo = re.findall(inq, item)if len(inqInfo) == 0:data.append(" ")else:data.append(inqInfo[0])matches = re.findall(findBd, item)if matches: # 確保列表非空bd = matches[0]else:bd = None # 或設定默認值/拋出異常# [('\n 導演: 弗蘭克·德拉邦特 Frank Darabont\xa0\xa0\xa0主演: 蒂姆·羅賓斯 Tim Robbins /...<br/>\n 1994\xa0/\xa0美國\xa0/\xa0犯罪 劇情\n ', '\n\n \n ')]# bd[0].replace(u'\xa0', '').replace('<br/>', '')# bd = re.sub('<\\s*b\\s*r\\s*/\\s*>', "", bd[0])# bd = re.sub('(\\s+)?', '', bd)data.append(bd)dataList.append(data)return dataListimport xlwtdef main():allData = []for i in range(0, 250, 25):url = baseurl + str(i)dataList = analysisData(url)allData.extend(dataList)savepath = "C:\pythonProject\python爬蟲\爬取豆瓣電影\豆瓣250.xls"book = xlwt.Workbook(encoding="utf-8", style_compression=0) # 創建Workbook對象sheet = book.add_sheet("豆瓣電影Top250", cell_overwrite_ok=True) # 創建工作表col = ("電影詳情鏈接", "圖片鏈接", "電影中/外文名", "評分", "評論人數", "概況", "相關信息")print(len(allData))for i in range(0, 7):sheet.write(0, i, col[i])for i in range(0, 250):print('正在保存第'+str((i+1))+'條')data = allData[i]for j in range(len(data)):sheet.write(i + 1, j, data[j])book.save(savepath)if __name__ == '__main__':main()