如何利用Playwright庫進(jìn)行電影網(wǎng)站數(shù)據(jù)的獲取
簡單概述
本系列可能是一個比較長的系列,主要是對《Python3網(wǎng)絡(luò)爬蟲開發(fā)實(shí)戰(zhàn)》前七章的一個內(nèi)容總結(jié)并且熟悉使用一下相關(guān)的框架與技術(shù)。
任務(wù)目標(biāo)
爬取電影數(shù)據(jù)網(wǎng)站ssr1.scrape.center/, 此網(wǎng)站無反爬,數(shù)據(jù)通過服務(wù)端渲染,需要爬取的部分為列表頁里面的電影數(shù)據(jù)詳情。
任務(wù)目標(biāo)解析
- 爬取ssr1.scrape.center/, 網(wǎng)站的列表頁面,通過列表頁面的內(nèi)容獲取到需要的URL
- 爬取ssr1.scrape.center/detail/{id}, 網(wǎng)站內(nèi)的數(shù)據(jù)詳情,需要獲取的部分有:
電影標(biāo)題
電影圖片的url
電影上映時間
電影分類
電影評分
劇情簡介
- 將內(nèi)容存放到需要的數(shù)據(jù)庫中
技術(shù)選型與爬取
如何爬取
playwright庫是微軟開源的一個庫,這個庫的功能更加的強(qiáng)大,除了可以實(shí)現(xiàn)同步操作,同樣也可以實(shí)現(xiàn)異步的操作,這個庫可以說是現(xiàn)在功能最強(qiáng)大的庫也不為過,因?yàn)槠溥€支持xpath,css選擇器等一些元素的選擇操作,甚至可以通過點(diǎn)擊鼠標(biāo)進(jìn)行操作,然后實(shí)現(xiàn)自動化構(gòu)建代碼,整體的功能真的十分強(qiáng)大。
構(gòu)建基礎(chǔ)的爬取函數(shù)
# 抓取網(wǎng)頁內(nèi)容 def scrape_page(page, url): logging.info('scraping %s ...', url) try: page.goto(url) page.wait_for_load_state('networkidle') except: logging.error('error occured while scraping %s', url, exc_info=True)
對于網(wǎng)頁內(nèi)容的操作,我們只需要對頁面選項(xiàng)卡進(jìn)行操作,傳入頁面選項(xiàng)卡對象和url鏈接實(shí)現(xiàn)我們想要完成的頁面請求,在這種請求下,我們通過等待網(wǎng)絡(luò)請求的響應(yīng)情況來判斷頁面是否完全響應(yīng)。
構(gòu)建列表頁的爬取函數(shù)
這個部分只需要分析出最基礎(chǔ)的URL的頁碼規(guī)則就可以完成對頁面內(nèi)容的爬取,經(jīng)過分析我們可以發(fā)現(xiàn)https://ssr1.scrape.center/page/{page}
可以發(fā)現(xiàn)變動的內(nèi)容在{page}
部分,因此構(gòu)建的抓取方式如下:
def scrape_index(page, page_index): index_url = f'{BASE_URL}/page/{page_index}' return scrape_page(page, index_url)
構(gòu)建詳情頁的爬取函數(shù)
詳情頁的爬取是建立在解析列表的基礎(chǔ)上獲得的,因此詳情頁爬取函數(shù)只需要知道url就可以直接調(diào)用基礎(chǔ)爬取函數(shù),而這里我們只需要對列表頁解析后就可以獲取到我們所需要的url,因此整體的構(gòu)建方式如下:
def scrape_detail(page, url): return scrape_page(page, url)
如何解析
解析列表頁后獲取詳情頁的URL
快速便捷的選擇器讓我們通過一行代碼就獲取到我們所需要的標(biāo)簽與屬性,十分方便的完成了我們需要獲取詳情頁的URL.
# 獲取解析內(nèi)容 def parse_index(page): # 獲取網(wǎng)頁內(nèi)容請求 elements = page.query_selector_all('a.name') # 獲取元素信息 for element in elements: part_of_url = element.get_attribute('href') detail_url = urljoin(BASE_URL, part_of_url) logging.info('get url: %s', detail_url) yield detail_url
解析詳情頁獲取需要的數(shù)據(jù)
當(dāng)詳情頁數(shù)據(jù)獲取到之后,對網(wǎng)頁內(nèi)的信息進(jìn)行解析,實(shí)現(xiàn)對電影名稱,電影類別,圖片地址,劇情簡介以及評分的內(nèi)容獲?。?/p>
def parse_detail(page): # 獲取標(biāo)題 name = None name_tag = page.query_selector('h2.m-b-sm') if name_tag: name = name_tag.text_content() # 獲取圖片 cover = None cover_tag = page.query_selector('img.cover') if cover_tag: cover = cover_tag.get_attribute('src') # 獲取分類 categories = [] category_tags = page.query_selector_all('div.categories > button > span') if category_tags: categories = [category.text_content() for category in category_tags] # 獲取評分 score = None score_tag = page.query_selector('p.score') if score_tag: score = score_tag.text_content().strip() # 劇情簡介 drama = None drama_tag = page.query_selector('div.drama > p') if drama_tag: drama = drama_tag.text_content().strip() return { # 標(biāo)題 'name': name, # 圖片 'cover': cover, # 分類 'categories': categories, # 簡介 'drama': drama, # 評分 'score': score }
如何存儲
本次存儲使用txt文本進(jìn)行文件內(nèi)容的存儲,直接將文件內(nèi)容寫入一個txt文件當(dāng)中。
# 數(shù)據(jù)內(nèi)容存儲 def save_data(data): # 文件存放地址 data_path = '{0}/movies.txt'.format(RESULT_DIR) # 進(jìn)行文件寫入 with open(data_path, 'a+', encoding='utf-8') as file: name = data.get('name', None) cover = data.get('cover', None) categories = data.get('categories', None) drama = data.get('drama', None) score = data.get('score', None) file.write('name:'+name+'\n') file.write('cover:'+cover+'\n') file.write('categories:'+str(categories)+'\n') file.write('drama:'+drama+'\n') file.write('score:'+score+'\n') file.write('='*50 + '\n')
源代碼
import logging from os import makedirs from os.path import exists from urllib.parse import urljoin from playwright.sync_api import sync_playwright logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s: %(message)s') # BASE_URL = 'https://ssr1.scrape.center' TOTAL_PAGE = 10 RESULT_DIR = 'results' exists(RESULT_DIR) or makedirs(RESULT_DIR) # 抓取網(wǎng)頁內(nèi)容 def scrape_page(page, url): logging.info('scraping %s ...', url) try: page.goto(url) page.wait_for_load_state('networkidle') except: logging.error('error occured while scraping %s', url, exc_info=True) def scrape_index(page, page_index): index_url = f'{BASE_URL}/page/{page_index}' return scrape_page(page, index_url) def scrape_detail(page, url): return scrape_page(page, url) # 獲取解析內(nèi)容 def parse_index(page): # 獲取網(wǎng)頁內(nèi)容請求 elements = page.query_selector_all('a.name') # 獲取元素信息 for element in elements: part_of_url = element.get_attribute('href') detail_url = urljoin(BASE_URL, part_of_url) logging.info('get url: %s', detail_url) yield detail_url def parse_detail(page): # 獲取標(biāo)題 name = None name_tag = page.query_selector('h2.m-b-sm') if name_tag: name = name_tag.text_content() # 獲取圖片 cover = None cover_tag = page.query_selector('img.cover') if cover_tag: cover = cover_tag.get_attribute('src') # 獲取分類 categories = [] category_tags = page.query_selector_all('div.categories > button > span') if category_tags: categories = [category.text_content() for category in category_tags] # 獲取評分 score = None score_tag = page.query_selector('p.score') if score_tag: score = score_tag.text_content().strip() # 劇情簡介 drama = None drama_tag = page.query_selector('div.drama > p') if drama_tag: drama = drama_tag.text_content().strip() return { # 標(biāo)題 'name': name, # 圖片 'cover': cover, # 分類 'categories': categories, # 簡介 'drama': drama, # 評分 'score': score } # 數(shù)據(jù)內(nèi)容存儲 def save_data(data): # 文件存放地址 data_path = '{0}/movies.txt'.format(RESULT_DIR) # 進(jìn)行文件寫入 with open(data_path, 'a+', encoding='utf-8') as file: name = data.get('name', None) cover = data.get('cover', None) categories = data.get('categories', None) drama = data.get('drama', None) score = data.get('score', None) file.write('name:'+name+'\n') file.write('cover:'+cover+'\n') file.write('categories:'+str(categories)+'\n') file.write('drama:'+drama+'\n') file.write('score:'+score+'\n') file.write('='*50 + '\n') def main(): with sync_playwright() as p: browser = p.chromium.launch(headless=False) page = browser.new_page() for page_index in range(1, TOTAL_PAGE + 1): scrape_index(page, page_index) detail_urls = list(parse_index(page)) for detail_url in detail_urls: scrape_detail(page, detail_url) data = parse_detail(page) logging.info('get data: %s', data) save_data(data) browser.close() if __name__ == '__main__': main()
版權(quán)信息
本文由PorterZhang整理或?qū)懽魍瓿?br />本人的Github: PorterZhang2021
本人的博客地址:PorterZhang
到此這篇關(guān)于如何利用Playwright庫進(jìn)行電影網(wǎng)站數(shù)據(jù)的獲取的文章就介紹到這了,更多相關(guān)Playwright庫電影網(wǎng)站數(shù)據(jù)的獲取內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pyx文件 生成pyd 文件用于 cython調(diào)用的實(shí)現(xiàn)
這篇文章主要介紹了pyx文件 生成pyd 文件用于 cython調(diào)用的實(shí)現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-03-03python向json中追加數(shù)據(jù)的兩種方法總結(jié)
JSON用來存儲和交換文本信息,比xml更小/更快/更易解析,下面這篇文章主要給大家介紹了關(guān)于python向json中追加數(shù)據(jù)的兩種方法,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05pandas數(shù)據(jù)篩選和csv操作的實(shí)現(xiàn)方法
這篇文章主要介紹了pandas數(shù)據(jù)篩選和csv操作的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-07-07python linecache 處理固定格式文本數(shù)據(jù)的方法
今天小編就為大家分享一篇python linecache 處理固定格式文本數(shù)據(jù)的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01