網頁

2023年3月6日 星期一

使用Python 做 Yahoo電影爬蟲

最近在寫LINE-bot聊天機器人,有個功能是查詢Yahoo電影的本週新片功能,有參考了網路上的一些方法,不過有些項目爬不下來有可能是Yahoo電影的網頁格式有改過,我把我修改的版本分享給大家順便可以練習爬蟲。


1.首先載入相關的套件:

 
import requests
from bs4 import BeautifulSoup
import pyshorteners as ps
 

說明:

requests:requests套件支援了HTTP的各種請求方法,其中GET與POST是最常使用到方式。
BeautifulSoup:BeautifulSoup是一個用來解析HTML結構的套件,將取回的網頁HTML結構,透過其提供的方法(Method),能夠輕鬆的搜尋及擷取網頁上所需的資料。
pyshorteners:縮短網址的套件。

2.將網頁爬取下來:

 
url = "https://movies.yahoo.com.tw/movie_thisweek.html"
# 使用 http GET 請求 url 的內容
response = requests.get(url)
# 擷取 request 回傳的文字部分
web_content = response.text
# 使用 BeautifulSoup 來 parse 網頁的內容
soup = BeautifulSoup(web_content,'lxml')
soup_items = soup.find_all("div", {"class":"release_info"})
 

3.現在網頁資訊都在soup_items變數內,內容大概是這樣:
 

4.現在要將本週新片的中文電影名稱取出,我們到Yahoo電影的本週新片頁面用F12來看網頁內容:

4.用迴圈將資訊取出,使用 find 方法找出字串中是否包含子字符串"release_movie_name",就是電影新片中文名稱 (strip()是將取出的字串前後空白刪除)。   

 
for index, item in enumerate(soup_items):
# 中文片名
name = item.find("div", {"class":"release_movie_name"}).a.text.strip()
 

5.用這方法可以依序找出英文片名,上映時間的資訊:

    
    # 英文片名
en = item.find("div", {"class":"en"}).a.text.strip()
# 上映時間
release_time = item.find("div",
{"class":"release_movie_time"}).\
text.split(':')[-1].strip()
 

6.接下來是"期待度"資訊,網路上大多用 div 標籤裡面的 span 標籤,不過這方式試過不行,直接用 "leveltext" 標籤就好。

 

為了不要因為抓到 None值會出現錯誤,還是給個條件測試一下比較保險:   

     
    # 期待度
    level = 'No Data' if item.find("div", {"class":"leveltext"}) is None \
else item.find("div", {"class":"leveltext"}).span.text
 

7.接著是取出預告片網址連結,在"btn_s_vedio"標籤內。
   

取出"btn_s_vedio"標籤的 href 值(就是預告片網址):

    
    # 預告片連結
tag1 = item.find('a', class_="btn_s_vedio")
trailer = tag1.get("href")
trailer = '-無預告片-' if trailer is None else trailer    
 

或是:

 
    trailer if not trailer is None else '-無預告片-'
 

tag1 和 trailer 也可以合併寫成:  

    
    trailer = item.find('a',class_="btn_s_vedio gabtn")['href']
 

不過當沒有預告片連結的時候會出錯,因為 href 的值會是 None,所以不建議這樣寫。

trailer 的值如下:


8.利用 pyshorteners 將新片連結的長網址改成短網址,如果沒有預告片網址就將直改為'-無預告片-':   
     
    # 縮網址
short_url = ps.Shortener().tinyurl.short(trailer) \
if not trailer is None else '-無預告片-'
 

9.印出結果:   
     
    print(f'{index + 1:>2d}.電影名稱:{name}')
print(f' 英文片名:{en}')
print(f' 上映時間:{release_time}')
print(f' 期待度:{level}')
print(f' 預告片:{trailer}')
print(f' 短連結:{short_url}')
print('-' * 50)
 


10.原始碼如下:

 
import requests
from bs4 import BeautifulSoup
import pyshorteners as ps

url = "https://movies.yahoo.com.tw/movie_thisweek.html"
# 使用 http GET 請求 url 的內容
response = requests.get(url)
# 擷取 request 回傳的文字部分
web_content = response.text
# 使用 BeautifulSoup 來 parse 網頁的內容
soup = BeautifulSoup(web_content,'lxml')
soup_items = soup.find_all("div", {"class":"release_info"})
for index, item in enumerate(soup_items):
# 中文片名
name = item.find("div", {"class":"release_movie_name"}).a.text.strip()
# 英文片名
en = item.find("div", {"class":"en"}).a.text.strip()
# 上映時間
release_time = item.find("div",
{"class":"release_movie_time"}).\
text.split(':')[-1].strip()
# 期待度
level = item.find("div", {"class":"leveltext"}).span.text
# 預告片連結
tag1 = item.find('a', class_="btn_s_vedio")
trailer = tag1.get("href")
#trailer = item.find('a',class_="btn_s_vedio gabtn")['href']
#trailer = '-無預告片-' if trailer is None else trailer
trailer if not trailer is None else '-無預告片-'
# 縮網址
short_url = ps.Shortener().tinyurl.short(trailer) \
if not trailer is None else '-無預告片-'
print(f'{index + 1:>2d}.電影名稱:{name}')
print(f' 英文片名:{en}')
print(f' 上映時間:{release_time}')
print(f' 期待度:{level}')
print(f' 預告片:{trailer}')
print(f' 短連結:{short_url}')
print('-' * 50)
 

執行結果: 

 
 






沒有留言:

張貼留言