使用Python獲取愛奇藝電視劇彈幕數據的示例代碼
本文的文字及圖片來源於網絡,僅供學習、交流使用,不具有任何商業用途,如有問題請及時聯系我們以作處理。
以下文章來源於數據STUDIO,作者龍哥帶你飛
Python分析抖音用戶行為數據視頻講解地址
https://www.bilibili.com/video/BV1yp4y1q7ZC/
數據獲取是數據分析中的重要的一步,數據獲取的途徑多種多樣,在這個信息爆炸的時代,數據獲取的代價也是越來越小。因此如此,仍然有很多小夥伴們無法如何獲取有用信息。此處以最近的熱播排行榜第一名的《流金歲月》為例,手把手教你如何獲取愛奇藝電視劇彈幕數據。
尋找彈幕信息
愛奇藝的彈幕數據已通過.z形式的壓縮文件存在,先通過以下步驟找到彈幕url, tvid列表,再獲取壓縮文件。利用工具對獲取的壓縮文件進行解壓,處理,存儲及分析。
絕對,實行多頁爬取,需要分析url規律,利用url規律循環請求並獲取所需內容。
此彈幕文件url地址為
https://cmts.iqiyi.com/bullet/93/00/6024766870349300_300_1.z
其中tvid = 6024766870349300
url普適形式為
url =’https:
//cmts.iqiyi.com/bullet/{}/{}/{}_300_{}.z’其中第一個與第二個花括號內容是tvid後3、4位,,後1、2位。第三個花括號為tvid。第四個花括號為子文件序號,其不是一個無窮大的數,會根據不同的電視劇有不同的最大數。
獲取彈幕文件
可以利用瀏覽器通過url直接請求,並獲取結果。
輸入網址可獲取彈幕內容的壓縮文件文件。
利用解壓/壓縮包zlib對下載下來的壓縮文件進行解壓查看。
import zlib from bs4 import BeautifulSoup with open(r"C:\Users\HP\Downloads\6024766870349300_300_10.z", 'rb') as fin: content = fin.read() btArr = bytearray(content) xml=zlib.decompress(btArr).decode('utf-8') bs = BeautifulSoup(xml,"xml") bs
輸出
因此tvid隻要獲得就能輕松獲取該電視劇的彈幕文件數據。
import zlib from bs4 import BeautifulSoup import pandas as pd import requests def get_data(tv_name,tv_id): """ 獲取每集的tvid :param tv_name: 集數,第1集、第2集... :param tv_id: 每集的tvid :return: DataFrame, 最終的數據 """ base_url = 'https://cmts.iqiyi.com/bullet/{}/{}/{}_300_{}.z' # 新建一個隻有表頭的DataFrame head_data = pd.DataFrame(columns=['uid','contentsId','contents','likeCount']) for i in range(1,20): url = base_url.format(tv_id[-4:-2],tv_id[-2:],tv_id,i) print(url) res = requests.get(url) if res.status_code == 200: btArr = bytearray(res.content) xml=zlib.decompress(btArr).decode('utf-8') # 解壓壓縮文件 bs = BeautifulSoup(xml,"xml") # BeautifulSoup網頁解析 data = pd.DataFrame(columns=['uid','contentsId','contents','likeCount']) data['uid'] = [i.text for i in bs.findAll('uid')] data['contentsId'] = [i.text for i in bs.findAll('contentId')] data['contents'] = [i.text for i in bs.findAll('content')] data['likeCount'] = [i.text for i in bs.findAll('likeCount')] else: break head_data = pd.concat([head_data,data],ignore_index = True) head_data['tv_name']= tv_name return head_data
獲取tvid
上文已通過tvid獲取到瞭彈幕文件數據,那麼如何獲取tvid又變成瞭一個問題。莫急,我們繼續分析。直接Ctrl + F搜索tvid
因此可以直接從返回結果中通過正則表達式獲取tvid。
from requests_html import HTMLSession, UserAgent from bs4 import BeautifulSoup import re def get_tvid(url): """ 獲取每集的tvid :param url: 請求網址 :return: str, 每集的tvid """ session = HTMLSession() #創建HTML會話對象 user_agent = UserAgent().random #創建隨機請求頭 header = {"User-Agent": user_agent} res = session.get(url, headers=header) res.encoding='utf-8' bs = BeautifulSoup(res.text,"html.parser") pattern =re.compile(".*?tvid.*?(\d{16}).*?") # 定義正則表達式 text_list = bs.find_all(text=pattern) # 通過正則表達式獲取內容 for t in range(len(text_list)): res_list = pattern.findall(text_list[t]) if not res_list: pass else: tvid = res_list[0] return tvid
由此問題tvid。來每一集都有一個tvid,有多少集電視劇就可以獲取多少個tvid。那麼問題又來瞭:獲取tvid時,是通過url發送請求,從返回結果中獲取。而每一集的url又該如何獲取呢。
獲取每集url
通過元素選擇工具定位到集數選擇信息。通過硒模擬瀏覽器獲取動態加載信息。
有小夥伴會說,可以直接直接從返回內容中獲取此href網址啊,你可以自己動手嘗試下。
雲朵君嘗試後得到的結果是href=”javascript:void(0);” rel=”external nofollow” ,因此解決這一問題的方法之一是運用硒模擬瀏覽器獲取js動態加載信息。
def get_javascript0_links(url, class_name, class_name_father, sleep_time=0.02): """ Selenium模擬用戶點擊爬取url :param url: 目標頁面 :param class_name: 模擬點擊的類 :param class_name_father: 模擬點擊的類,此類為class_name的父類 :param sleep_time: 留給頁面後退的時間 :return: list, 點擊class為class_name進去的超鏈接 """ def wait(locator, timeout=15): """等到元素加載完成""" WebDriverWait(driver, timeout).until(EC.presence_of_element_located(locator)) options = Options() # options.add_argument("--headless") # 無界面,若你需要查看界面內容,可以將此行註釋掉 driver = webdriver.Chrome(options=options) driver.get(url) locator = (By.CLASS_NAME, class_name) wait(locator) element = driver.find_elements_by_class_name(class_name_father) elements = driver.find_elements_by_class_name(class_name) link = [] linkNum = len(elements) for j in range(len(element)): wait(locator) driver.execute_script("arguments[0].click();", element[j]) # 模擬用戶點擊 for i in range(linkNum): print(i) wait(locator) elements = driver.find_elements_by_class_name(class_name) # 再次獲取元素,預防StaleElementReferenceException driver.execute_script("arguments[0].click();", elements[i]) # 模擬用戶點擊 time.sleep(sleep_time) link.append(driver.current_url) time.sleep(sleep_time) driver.back() driver.quit() return link if __name__ == "__main__": url = "https://www.iqiyi.com/v_1meaw5kgh3s.html" class_name = "qy-episode-num" link = get_javascript0_links(url, class_name, class_name_father="tab-bar") for i, _link in enumerate(link): print(i, _link)
主函數
接下來通過主函數將所有步驟串起。
def main(sleep_second=0.02): url = "https://www.iqiyi.com/v_1meaw5kgh3s.html" class_name = "select-item" class_name_father = "bar-li" links = get_javascript0_links(url, class_name, class_name_father) head_data = pd.DataFrame(columns=['tv_name','uid','contentsId','contents','likeCount']) for num, link in enumerate(links): tv_name = f"第{num+1}集" tv_id = get_tvid(url=link) data = get_data(tv_name,tv_id) head_data = pd.concat([head_data,data],ignore_index = True) time.sleep(sleep_second) return head_data
獲取到的數據結果如下:
>>> data = main() >>> data.info() """ <class 'pandas.core.frame.DataFrame'> RangeIndex: 246716 entries, 0 to 246715 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 tv_name 246716 non-null object 1 uid 246716 non-null object 2 contentsId 246716 non-null object 3 contents 246716 non-null object 4 likeCount 246716 non-null object dtypes: object(5) memory usage: 9.4+ MB """ >>> data.sample(10)
詞雲圖先分詞
運用中文分詞庫jieba分詞,並去除撤銷詞。
def get_cut_words(content_series): """ :param content_series: 需要分詞的內容 :return: list, 點擊class為class_name進去的超鏈接 """ # 讀入停用詞表 import jieba stop_words = [] with open("stop_words.txt", 'r', encoding='utf-8') as f: lines = f.readlines() for line in lines: stop_words.append(line.strip()) # 添加關鍵詞 my_words = ['倪妮', '劉詩詩', '鎖鎖', '蔣三歲', '陳道明'] for i in my_words: jieba.add_word(i) # 自定義停用詞 my_stop_words = ['哈哈哈','哈哈哈哈', '真的'] stop_words.extend(my_stop_words) # 分詞 word_num = jieba.lcut(content_series.str.cat(sep='。'), cut_all=False) word_num_selected = [i for i in word_num if i not in stop_words and len(i)>=2] # 條件篩選 return word_num_selected
後畫圖
運用升級版詞雲圖庫stylecloud可視化彈幕結果。
import stylecloud from IPython.display import Image text1 = get_cut_words(content_series=data.contents) stylecloud.gen_stylecloud(text=' '.join(text1), collocations=False, font_path=r'C:\Windows\Fonts\msyh.ttc', icon_name='fas fa-rocket',size=400, output_name='流金歲月-詞雲.png') Image(filename='流金歲月-詞雲.png')
到此這篇關於使用Python獲取愛奇藝電視劇彈幕數據的示例代碼的文章就介紹到這瞭,更多相關Python獲取愛奇藝電視劇彈幕數據內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!
推薦閱讀:
- python自動化實現自動回復QQ消息
- selenium+python自動化78-autoit參數化與批量上傳功能的實現
- 分享7個 Python 實戰項目練習
- Python使用Beautiful Soup(BS4)庫解析HTML和XML
- Python爬蟲實戰之用selenium爬取某旅遊網站