本站AI自動(dòng)判斷提供您所需要的app下載:點(diǎn)我下載安裝,你懂的APP
【官方通報(bào):淫穢漫畫(huà)作者JM制販淫穢暴力漫畫(huà)被刑拘】23日,@掃黃打非 通報(bào):近期,網(wǎng)民反映淫穢漫畫(huà)作者JM,通過(guò)互聯(lián)網(wǎng)涉嫌非法銷(xiāo)售淫穢色情、血腥暴力漫畫(huà)。全國(guó)“掃黃打非”辦公室接到舉報(bào)線索,部署遼寧省“掃黃打非”部門(mén)核查偵辦。目前,蔣某某(JM為其化名)因涉嫌制作淫穢物品牟利罪被刑拘。
來(lái)源: 人民網(wǎng)
前言
本文的文字及圖片來(lái)源于網(wǎng)絡(luò),僅供學(xué)習(xí)、交流使用,不具有任何商業(yè)用途,版權(quán)歸原作者所有,如有問(wèn)題請(qǐng)及時(shí)聯(lián)系我們以作處理。
作者:merlin&
操作環(huán)境
編譯器:pycharm社區(qū)版
python 版本:anaconda python3.7.4
瀏覽器選擇:Google瀏覽器
需要用到的第三方模塊:requests , lxml , selenium , time , bs4,os
網(wǎng)頁(yè)分析
明確目標(biāo)
首先我們打開(kāi)騰訊動(dòng)漫首頁(yè),分析要抓取的目標(biāo)漫畫(huà)。找到騰訊動(dòng)漫的漫畫(huà)目錄頁(yè),簡(jiǎn)單看了一下目錄,發(fā)現(xiàn)全站的漫畫(huà)數(shù)量超過(guò)了三千部(感覺(jué)就是爬下來(lái)也會(huì)把內(nèi)存撐爆)
于是我覺(jué)得爬取首頁(yè)的推薦漫畫(huà)會(huì)是一個(gè)比較好的選擇(爬取全站漫畫(huà)只需要稍稍改一下網(wǎng)址構(gòu)造就可以做到了)
提取漫畫(huà)地址
選定了對(duì)象之后,就應(yīng)該想辦法來(lái)搞到漫畫(huà)的地址了右擊檢查元素,粗略看一遍網(wǎng)頁(yè)的源代碼,這時(shí)我發(fā)現(xiàn)里面有很多連續(xù)的
標(biāo)簽,我猜測(cè)每部漫畫(huà)的地址信息就存儲(chǔ)在這些標(biāo)簽里面
隨便打開(kāi)一個(gè)《li》標(biāo)簽,點(diǎn)擊里面包裹的鏈接地址會(huì)跳轉(zhuǎn)到一個(gè)新的網(wǎng)頁(yè),這個(gè)網(wǎng)頁(yè)正是我想要找的漫畫(huà)地址,可以見(jiàn)得我的猜測(cè)是正確的,等到實(shí)際操作的時(shí)候再用表達(dá)式提取信息就非常容易了
提取漫畫(huà)章節(jié)地址
進(jìn)入漫畫(huà)的目錄頁(yè),發(fā)現(xiàn)一頁(yè)最多可以展示20章的漫畫(huà)目錄,要想更換顯示還需要點(diǎn)擊章節(jié)名上面的選項(xiàng)卡來(lái)顯示其他章節(jié)的地址
接下來(lái)就需要我們來(lái)檢查網(wǎng)頁(yè)元素想辦法來(lái)獲取章節(jié)地址了,同樣右擊檢查元素在看到了源代碼后,我發(fā)現(xiàn)了一個(gè)非常驚喜的事情,這個(gè)源碼里面包含著所有的章節(jié)鏈接,而不是通過(guò)動(dòng)態(tài)加載來(lái)展示的,這就省去了我們提取其他章節(jié)鏈接的功夫,只需要花心思提取漫畫(huà)圖片就可以了
這里每個(gè)《p》標(biāo)簽下包含了五個(gè)《a》標(biāo)簽,每個(gè)《li》標(biāo)簽下包含了四個(gè)《p》標(biāo)簽,而每個(gè)漫畫(huà)的鏈接就存在每個(gè)《a》標(biāo)簽中,可以輕松通過(guò)語(yǔ)法來(lái)提取到每頁(yè)的鏈接信息
提取漫畫(huà)圖片
怎么將漫畫(huà)的圖片地址提取出來(lái)并保存到本地,這是這個(gè)代碼的難點(diǎn)和核心先是打開(kāi)漫畫(huà),這個(gè)漫畫(huà)頁(yè)應(yīng)該是被加上了某些措施,所以它沒(méi)辦法使用右鍵查看網(wǎng)頁(yè)源代碼,但是使用快捷鍵[ctrl + shift +i]是可以看到的
按下[ctrl + shift + i],檢查元素
通過(guò)第一次檢查,可以發(fā)現(xiàn)網(wǎng)頁(yè)的元素中只有前幾張圖片的地址信息,后面的信息都為后綴.gif的文件表示,這些gif文件就是圖片的加載動(dòng)畫(huà)
接著向下滑動(dòng)到底部,等待圖片全部顯示出來(lái)再次檢查元素
現(xiàn)在所有的漫畫(huà)圖片全部顯示出來(lái),下方并無(wú).gif 的文件,由此可知,騰訊動(dòng)漫是以js異步加載來(lái)顯示圖片的,要想獲取頁(yè)面的全部圖片,就必須要滑動(dòng)滾動(dòng)條,將全部的圖片加載完成再進(jìn)行提取,這里我選擇selenium模塊和chromedriver來(lái)幫助我完成這些操作。下面開(kāi)始進(jìn)行代碼的編寫(xiě)。
編寫(xiě)代碼
導(dǎo)入需要的模塊
import requests
from lxml import etree
from selenium import webdriver #selenium模擬操作
from time import sleep
from bs4 import BeautifulSoup
from selenium.webdriver.chrome.options import Options #谷歌無(wú)頭瀏覽器
import os
獲取漫畫(huà)地址
這里我使用的是xpath提取漫畫(huà)地址信息,在谷歌瀏覽器中使用xpath helper插件輔助編寫(xiě)xpath表達(dá)式
#打開(kāi)騰訊動(dòng)漫首頁(yè)
url = 'https://ac.qq.com/'
#給網(wǎng)頁(yè)發(fā)送請(qǐng)求
data = requests.get(url).text
#將網(wǎng)頁(yè)信息轉(zhuǎn)換成xpath可識(shí)別的類型
html = etree.HTML(data)
#提取到每個(gè)漫畫(huà)的目錄頁(yè)地址
comic_list = html.xpath('//a[@class="in-rank-name"]/@href')
print(comic_list)
print一下輸出的comic_list,提取成功
提取漫畫(huà)的內(nèi)容頁(yè)
內(nèi)容頁(yè)的提取也很簡(jiǎn)單,就像上面的分析一樣,使用簡(jiǎn)單的xpath語(yǔ)法即可提取
然后我們?cè)賹⒙?huà)的名字提取出來(lái),方便為保存的文件夾命名
#遍歷提取到的信息
for comic in comic_list:
#拼接成為漫畫(huà)目錄頁(yè)的網(wǎng)址
comic_url = url + str(comic)
#從漫畫(huà)目錄頁(yè)提取信息
url_data = requests.get(comic_url).text
#準(zhǔn)備用xpath語(yǔ)法提取信息
data_comic = etree.HTML(url_data)
#提取漫畫(huà)名--text()為提取文本內(nèi)容
name_comic = data_comic.xpath("http://h2[@class='works-intro-title ui-left']/strong/text()")
#提取該漫畫(huà)每一頁(yè)的地址
item_list = data_comic.xpath("http://span[@class='works-chapter-item']/a/@href")
print(name_comic)
print(item_list)
print打印的信息:
提取章節(jié)名
剛剛我們輸出的是漫畫(huà)頁(yè)的地址字段,但是通過(guò)這些字段并不能請(qǐng)求到信息,還需在前面加上域名才可以構(gòu)成一個(gè)完整的網(wǎng)址提取章節(jié)名是為了在漫畫(huà)名的文件夾下再為每個(gè)章節(jié)創(chuàng)建一個(gè)文件夾保存漫畫(huà)圖片
for item in item_list:
#拼接每一章節(jié)的地址
item_url = url + str(item)
#print(item_url)
#請(qǐng)求每一章節(jié)的信息
page_mes = requests.get(item_url).text
#準(zhǔn)備使用xpath提取內(nèi)容
page_ming = etree.HTML(page_mes)
#提取章節(jié)名
page_name = page_ming.xpath('//span[@class="title-comicHeading"]/text()')
print(page_name)
打印章節(jié)名:
獲取漫畫(huà)源網(wǎng)頁(yè)代碼
這個(gè)部分的代碼是這個(gè)代碼的核心部分,也是花費(fèi)時(shí)間最久的部分首先我們知道通過(guò)正常的方式?jīng)]有辦法請(qǐng)求到所有的圖片地址信息,若是使用抓包方法會(huì)變得非常難分析,所以我采用的是模擬瀏覽器滑動(dòng)的方法來(lái)獲得圖片的地址信息為了方便看到結(jié)果,先將webdriver設(shè)置為有界面模式,等到實(shí)現(xiàn)想要的功能之后,再將它隱藏起來(lái)
#webdriver位置
path = r'/home/jmhao/chromedriver'
#瀏覽器參數(shù)設(shè)置
browser = webdriver.Chrome(executable_path=path)
#開(kāi)始請(qǐng)求第一個(gè)章節(jié)的網(wǎng)址
browser.get(item_url)
#設(shè)置延時(shí),為后續(xù)做緩沖
sleep(2)
#嘗試執(zhí)行下列代碼
try:
#設(shè)置自動(dòng)下滑滾動(dòng)條操作
for i in range(1, 100):
#滑動(dòng)距離設(shè)置
js = 'var q=document.getElementById("mainView").scrollTop = ' + str(i * 1000)
#執(zhí)行滑動(dòng)選項(xiàng)
browser.execute_script(js)
#延時(shí),使圖片充分加載
sleep(2)
sleep(2)
#將打開(kāi)的界面截圖保存,證明無(wú)界面瀏覽器確實(shí)打開(kāi)了網(wǎng)頁(yè)
browser.get_screenshot_as_file(str(page_name) + ".png")
#獲取當(dāng)前頁(yè)面源碼
data = browser.page_source
#在當(dāng)前文件夾下創(chuàng)建html文件,并將網(wǎng)頁(yè)源碼寫(xiě)入
fh = open("dongman.html", "w", encoding="utf-8")
#寫(xiě)入操作
fh.write(data)
#關(guān)掉瀏覽器
fh.close()
# 若上述代碼執(zhí)行報(bào)錯(cuò)(大概率是由于付費(fèi)漫畫(huà)),則執(zhí)行此部分代碼
except Exception as err:
#跳過(guò)錯(cuò)誤代碼
pass
運(yùn)行之后會(huì)自動(dòng)打開(kāi)漫畫(huà)的內(nèi)容頁(yè),并拖動(dòng)右側(cè)的滑動(dòng)條(模擬了手動(dòng)操作,緩慢拖動(dòng)是為了讓圖片充分加載),其中的sleep方法和網(wǎng)速有一定的關(guān)系,網(wǎng)速好的可以適當(dāng)減少延時(shí)的時(shí)間,網(wǎng)速差可適當(dāng)延長(zhǎng)在寫(xiě)拖動(dòng)滑動(dòng)條的代碼時(shí),我嘗試了非常多種拖動(dòng)寫(xiě)法,也模擬了按下方向鍵的操作,可是只有這一種方法使用成功了。我認(rèn)為失敗的原因可能是剛打開(kāi)界面的時(shí)候會(huì)有一個(gè)導(dǎo)航條擋住滑塊,導(dǎo)致無(wú)法定位到滑塊的坐標(biāo)(因?yàn)槲矣闷渌W(wǎng)頁(yè)測(cè)試的時(shí)候都是可以拖動(dòng)的)
使用的try是為了防止有一些章節(jié)會(huì)彈出付費(fèi)窗口,導(dǎo)致程序報(bào)錯(cuò),使后續(xù)無(wú)法運(yùn)行,即遇到會(huì)報(bào)錯(cuò)的情況就跳過(guò)此段代碼,執(zhí)行except中的選項(xiàng)
這段程序運(yùn)行完之后有一個(gè)dongman.html文件保存在當(dāng)前文件夾下,里面就包含了所有圖片的url,接下來(lái)只要讀取這個(gè)文件的內(nèi)容就可以提取到所有的漫畫(huà)地址了
下載漫畫(huà)圖片
當(dāng)我們保存完網(wǎng)頁(yè)的源代碼之后,接下來(lái)的操作就變得簡(jiǎn)單了 我們要做的就是提取文件內(nèi)容,將圖片下載到本地
#用beautifulsoup打開(kāi)本地文件
html_new = BeautifulSoup(open('dongman.html', encoding='utf-8'), features='html.parser')
#提取html文件中的主體部分
soup = html_new.find(id="mainView")
#設(shè)置變量i,方便為保存的圖片命名
i = 0
#提取出主體部分中的img標(biāo)簽(因?yàn)閳D片地址保存在img標(biāo)簽中)
for items in soup.find_all("img"):
#提取圖片地址信息
item = items.get("src")
#請(qǐng)求圖片地址
comic_pic = requests.get(item).content
#print(comic_pic)
#嘗試提取圖片,若發(fā)生錯(cuò)誤則跳過(guò)
try:
#打開(kāi)文件夾,將圖片存入
with open('comic/' + str(name_comic) + '/' + str(page_name) + '/' + str(i + 1) + '.jpg', 'wb') as f:
#print('正在下載第 ', (i + 1), ' 張圖片中')
print('正在下載' , str(name_comic) , '-' , str(page_name) , '- 第' , (i+1) , '張圖片')
#寫(xiě)入操作
f.write(comic_pic)
#更改圖片名,防止新下載的圖片覆蓋原圖片
i += 1
#若上述代碼執(zhí)行報(bào)錯(cuò),則執(zhí)行此部分代碼
except Exception as err:
#跳過(guò)錯(cuò)誤代碼
pass
下載結(jié)果
到了這里代碼就寫(xiě)完了,來(lái)看一下運(yùn)行結(jié)果:
打開(kāi)文件夾看到:
完整代碼
import requests
from lxml import etree
from selenium import webdriver
from time import sleep
from bs4 import BeautifulSoup
from selenium.webdriver.chrome.options import Options
import os
'''
============================
python學(xué)習(xí)群:695185429
============================
'''
#打開(kāi)騰訊動(dòng)漫首頁(yè)
url = 'https://ac.qq.com/'
#給網(wǎng)頁(yè)發(fā)送請(qǐng)求
data = requests.get(url).text
#將網(wǎng)頁(yè)信息轉(zhuǎn)換成xpath可識(shí)別的類型
html = etree.HTML(data)
#提取到每個(gè)漫畫(huà)的目錄頁(yè)地址
comic_list = html.xpath('//a[@class="in-rank-name"]/@href')
#print(comic_list)
#遍歷提取到的信息
for comic in comic_list:
#拼接成為漫畫(huà)目錄頁(yè)的網(wǎng)址
comic_url = url + str(comic)
#從漫畫(huà)目錄頁(yè)提取信息
url_data = requests.get(comic_url).text
#準(zhǔn)備用xpath語(yǔ)法提取信息
data_comic = etree.HTML(url_data)
#提取漫畫(huà)名--text()為提取文本內(nèi)容
name_comic = data_comic.xpath("http://h2[@class='works-intro-title ui-left']/strong/text()")
#提取該漫畫(huà)每一頁(yè)的地址
item_list = data_comic.xpath("http://span[@class='works-chapter-item']/a/@href")
# print(name_comic)
# print(item_list)
#以漫畫(huà)名字為文件夾名創(chuàng)建文件夾
os.makedirs('comic/' + str(name_comic))
#將一本漫畫(huà)的每一章地址遍歷
for item in item_list:
#拼接每一章節(jié)的地址
item_url = url + str(item)
#print(item_url)
#請(qǐng)求每一章節(jié)的信息
page_mes = requests.get(item_url).text
#準(zhǔn)備使用xpath提取內(nèi)容
page_ming = etree.HTML(page_mes)
#提取章節(jié)名
page_name = page_ming.xpath('//span[@class="title-comicHeading"]/text()')
#print(page_name)
#再以章節(jié)名命名一個(gè)文件夾
os.makedirs('comic/' + str(name_comic) + '/' + str(page_name))
#以下為代碼的主體部分
#設(shè)置谷歌無(wú)界面瀏覽器
chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
#webdriver位置
path = r'/home/jmhao/chromedriver'
#瀏覽器參數(shù)設(shè)置
browser = webdriver.Chrome(executable_path=path, options=chrome_options)
#開(kāi)始請(qǐng)求第一個(gè)章節(jié)的網(wǎng)址
browser.get(item_url)
#設(shè)置延時(shí),為后續(xù)做緩沖
sleep(2)
#browser.get_screenshot_as_file(str(page_name) + ".png")
#嘗試執(zhí)行下列代碼
try:
#設(shè)置自動(dòng)下滑滾動(dòng)條操作
for i in range(1, 100):
#滑動(dòng)距離設(shè)置
js = 'var q=document.getElementById("mainView").scrollTop = ' + str(i * 1000)
#執(zhí)行滑動(dòng)選項(xiàng)
browser.execute_script(js)
#延時(shí),使圖片充分加載
sleep(2)
sleep(2)
#將打開(kāi)的界面截圖保存,證明無(wú)界面瀏覽器確實(shí)打開(kāi)了網(wǎng)頁(yè)
browser.get_screenshot_as_file(str(page_name) + ".png")
#獲取當(dāng)前頁(yè)面源碼
data = browser.page_source
#在當(dāng)前文件夾下創(chuàng)建html文件,并將網(wǎng)頁(yè)源碼寫(xiě)入
fh = open("dongman.html", "w", encoding="utf-8")
#寫(xiě)入操作
fh.write(data)
#關(guān)掉無(wú)界面瀏覽器
fh.close()
#下面的操作為打開(kāi)保存的html文件,提取其中的圖片信息,并保存到文件夾中
#用beautifulsoup打開(kāi)本地文件
html_new = BeautifulSoup(open('dongman.html', encoding='utf-8'), features='html.parser')
#提取html文件中的主體部分
soup = html_new.find(id="mainView")
#設(shè)置變量i,方便為保存的圖片命名
i = 0
#提取出主體部分中的img標(biāo)簽(因?yàn)閳D片地址保存在img標(biāo)簽中)
for items in soup.find_all("img"):
#提取圖片地址信息
item = items.get("src")
#請(qǐng)求圖片地址
comic_pic = requests.get(item).content
#print(comic_pic)
#嘗試提取圖片,若發(fā)生錯(cuò)誤則跳過(guò)
try:
#打開(kāi)文件夾,將圖片存入
with open('comic/' + str(name_comic) + '/' + str(page_name) + '/' + str(i + 1) + '.jpg', 'wb') as f:
#print('正在下載第 ', (i + 1), ' 張圖片中')
print('正在下載' , str(name_comic) , '-' , str(page_name) , '- 第' , (i+1) , '張圖片')
#寫(xiě)入操作
f.write(comic_pic)
#更改圖片名,防止新下載的圖片覆蓋原圖片
i += 1
#若上述代碼執(zhí)行報(bào)錯(cuò),則執(zhí)行此部分代碼
except Exception as err:
#跳過(guò)錯(cuò)誤代碼
pass
# 若上述代碼執(zhí)行報(bào)錯(cuò)(大概率是由于付費(fèi)漫畫(huà)),則執(zhí)行此部分代碼
except Exception as err:
#跳過(guò)錯(cuò)誤代碼
pass