利用python爬取,python爬取B站番劇索引頁面并保存文本和圖片

 2023-10-13 阅读 33 评论 0

摘要:該篇文章為"行路難=_="原創 期末的Python考試要寫一個爬取網站信息的程序,我就選取了b站番劇索引頁面作為目標網頁(因為感覺番劇主頁的信息太雜了。) 利用python爬取,目標網頁:https://www.bilibili.com/anime/index 原本打算魔

該篇文章為"行路難=_="原創

期末的Python考試要寫一個爬取網站信息的程序,我就選取了b站番劇索引頁面作為目標網頁(因為感覺番劇主頁的信息太雜了。)

利用python爬取,目標網頁:https://www.bilibili.com/anime/index

原本打算魔改老師給的范例使用BeautifulSoup庫來解析html獲取數據的,
但是在運行的時候發現。好像獲取不了數據?

python編程。原先使用的代碼:
app.py (主程序)

import requests
from bs4 import BeautifulSoup
from writetext import TextStorage
from datetime import datetime
import osclass MySpider(object):header = {"Referer": "","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36",}def __init__(self, url, directory):self.s = requests.Session()self.url = urlself.dir = directoryif not os.path.exists(directory):os.mkdir(directory)self.idx = 0def crawling(self):rsp = self.s.get(self.url, headers=MySpider.header)soup = BeautifulSoup(rsp.text,"html.parser")tag = soup.find("ul", class_="bangumi-list") # 該處設置斷點tags_li = tag.find_all("li") # 該處設置斷點with TextStorage() as xs:for li in tags_li:image_url = "https:%s" % li.a.div.img['src'] # 這個獲取番劇封面print(image_url)filename = self.save_image(image_url)content = li.find("a", class_="bangumi-title").string # 這個獲取番劇標題url = self.dir + '/' + filenamexs.write(content, url)def save_image(self, image_url):image = self.s.get(image_url, headers=MySpider.header)now = datetime.now()suffix = now.strftime('%Y%m%d_%H%M')name = "img_%s_%d.jpg" % (suffix, self.idx)self.idx += 1with open(self.dir + '/' + name, 'wb') as file:file.write(image.content)return nameif __name__ == "__main__":MySpider("https://www.bilibili.com/anime/index", # 爬取的目標網頁"./爬取的圖片").crawling() # 爬取的圖片存放位置

writetext.py (文本保存模塊)

from datetime import datetime
import os
class TextStorage(object):def __init__(self):self.enter_flag = 0def __enter__(self):self.enter_flag = 1now = datetime.now()suffix = now.strftime('%Y%m%d_%H%M')self.file_name = "./爬取的摘要文檔_%s.txt" % (suffix)self.textStorage = open(self.file_name, "a+" , encoding='utf-8')return selfdef __exit__(self, Type, value, traceback):if self.enter_flag:self.save()self.textStorage.close()else:os.remove(self.file_name)def write(self, content, image_url):self.textStorage.write("%s%s\n" % (content, image_url))def save(self):self.textStorage.flush()def read(self):ret = []old_pos = self.textStorage.tell()self.textStorage.seek(0)lines = self.textStorage.readlines()self.textStorage.seek(old_pos)idx = 0content = ""image_url = ""for line in lines:if idx == 0:content = lineidx += 1elif idx == 1:image_url = lineidx += 1ret.append((content, image_url))else:idx = 0return retdef seek(self, whence, offset):self.textStorage.seek(whence, offset)

python爬蟲教程。運行起這個代碼,什么也沒有顯示就退出了,說明中間出錯了。
在tags_li處設置斷點進行調試,發現tags_li的長度為0,tag獲取的數據顯示為“加載中”
說明了b站番劇索引頁面的數據無法通過靜態獲取。
這里參考了python爬取B站番劇鏈接

所以現在通過F12查找頁面的API接口。
步驟1:進入目標網頁,F12打開開發人員工具
默認是在控制臺(Console)或元素(Elements)頁面
我們切換到網絡(Network)標簽頁

步驟2:點擊F5刷新頁面,等待頁面加載完成后,
點擊這個網絡標簽頁中沒有任何一個按鈕的空白處
同時按下“Ctrl”+“F”鍵,將在左邊分出一個搜索框
在框里面輸入api后點擊回車,將顯示許多個結果
在這里插入圖片描述
步驟3:將開發工具頁面拉大一點方便看,然后只點擊搜索結果中紅線劃出的URL那行。
隨便點一個,就能看到右邊的區域顯示了標頭(Headers)標簽頁,
我們直接切換到預覽(Preview)的標簽頁。
然后開始查看所有搜索結果里的URL那行的預覽頁面
(如果搜索結果有折疊起的也必須展開看里面有沒有URL)

步驟4:預覽頁面中,如果顯示是圖片的,直接下一個。
如果是這樣顯示的,就點開這個data數組。
如果點開結果是類似這樣的,就也不是

直到我們點開一個預覽是這樣的URl結果:

點開里面的list數組:
好,這下就找到了B站的番劇索引API了。
切換回標頭(Headers)標簽頁,這個API的鏈接赫然在上。

復制這個API到Python,用我們的request來處理它。

于是,按照默認的追番人數排序從大到小的排序的番劇信息就可以爬下來了。
(由于接口信息就給了那么多,所以只能從這里看到追番人數、標題、話數等信息,無法看到番劇介紹,播放次數等內容。)
不過按照更新時間,評分,播放數量,開播時間排序的明顯也可以通過這個接口實現,具體實現不進行描述了。

最終程序成品效果:


👇
👇
👇
最后,將完整代碼放出:
app.py(主程序)

import requests
from bs4 import BeautifulSoup
from writetext import TextStorage
from datetime import datetime
import os
import jsonclass MySpider(object):header = {"Referer": "","User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.75 Safari/537.36",}def __init__(self, url, directory):self.s = requests.Session()self.url = urlself.dir = directoryif not os.path.exists(directory):os.mkdir(directory)self.idx = 0def crawling(self):print("開始爬取……")s = requests.get(self.url, headers=MySpider.header)if s.status_code == 200:animelist = s.json()['data']['list']with TextStorage() as xs:for li in animelist:anime_title = li['title']anime_order = li['order']anime_badge = li['badge']anime_index = li['index_show']anime_link = li['link']image_url = li['cover']filename = self.save_image(image_url)content = anime_title+"\t"+anime_order+"\n"+anime_index+"\t"+anime_badge + \"\n番劇鏈接:"+anime_link+"\n封面鏈接:"+image_url + \"\n封面存放位置:"+self.dir + '/'+filename+"\n"print(content)xs.write(content)def save_image(self, image_url):image = self.s.get(image_url, headers=MySpider.header)now = datetime.now()suffix = now.strftime('%Y%m%d_%H%M')name = "img_%s_%d.jpg" % (suffix, self.idx)self.idx += 1with open(self.dir + '/' + name, 'wb') as file:file.write(image.content)return name
if __name__ == "__main__":print("將爬取追番人數從高到低的番劇信息。\n不輸入或輸入非整數默認為20")while True:inp = Nonetry:inp = int(input("請輸入爬取數量:"))except:passif type(inp) == int:if inp >= 3142:print("超出范圍了!")continuenum = inpbreakif inp == None:num = 20breakurl = "https://api.bilibili.com/pgc/season/index/result?season_version=-1&area=-1&is_finish=-1&copyright=-1&season_status=-1&season_month=-1&year=-1&style_id=-1&order=3&st=1&sort=0&page=1&season_type=1&pagesize=%d&type=1" %numMySpider(url,"./爬取的圖片").crawling()

writetext.py(文本保存模塊)

from datetime import datetime
import osclass TextStorage(object):def __init__(self):self.enter_flag = 0def __enter__(self):self.enter_flag = 1now = datetime.now()suffix = now.strftime('%Y%m%d_%H%M')self.file_name = "./爬取的摘要文檔_%s.txt" % (suffix)self.textStorage = open(self.file_name, "a+" , encoding='utf-8')return selfdef __exit__(self, Type, value, traceback):if self.enter_flag:self.save()self.textStorage.close()else:os.remove(self.file_name)def write(self, content): # 這里進行了修改!!self.textStorage.write("%s\n" % (content)) # 這里進行了修改!!def save(self):self.textStorage.flush()def read(self):ret = []old_pos = self.textStorage.tell()self.textStorage.seek(0)lines = self.textStorage.readlines()self.textStorage.seek(old_pos)idx = 0content = ""image_url = ""for line in lines:if idx == 0:content = lineidx += 1elif idx == 1:image_url = lineidx += 1ret.append((content, image_url))else:idx = 0return retdef seek(self, whence, offset):self.textStorage.seek(whence, offset)

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://808629.com/142617.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 86后生记录生活 Inc. 保留所有权利。

底部版权信息