我使用BeautifulSoup和Selenium制作了一个简单的python脚本,可以自动从8个缪斯下载成人漫画。我之所以使用selenium,是因为该网站使用javascript加载图像。
输入图库url并下载位置开始下载。样本库urls:
https://www.8muses.com/comics/album/MilfToon-Comics/Milfage/Issue-1 https://www.8muses.com/comics/album/MilfToon-Comics/Lemonade/Lemonade-1
我想知道对代码或替代方法的改进,以使其工作得更快。谢谢!
代码: app.py
import os
from multiprocessing.dummy import Pool
from queue import Queue
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
from threading import Thread
import urllib.request
import requests
import shutil
options = Options()
options.headless = True
chrome_driver_path = r"C:\Users\NH\PycharmProjects\SeleniumTest\drivers\chromedriver.exe"
base_url = "https://www.8muses.com"
def fetch_image_url(url,filename,download_location):
driver = webdriver.Chrome(chrome_driver_path, chrome_options=options)
driver.get(url)
page = driver.page_source
soup = BeautifulSoup(page,"lxml")
image_url = "http:"+soup.find("img",{"class":"image"})['src']
download_image(image_url,filename,download_location)
def download_image(image_url,filename,download_location):
r = requests.get(image_url,stream=True, headers={'User-agent': 'Mozilla/5.0'})
if r.status_code == 200:
with open(os.path.join(download_location,str(filename)+".png"), 'wb') as f:
r.raw.decode_content = True
shutil.copyfileobj(r.raw, f)
print("Downloaded page {pagenumber}".format(pagenumber=filename))
if __name__=="__main__":
print("Album Url : ")
album_url = input()
print("Download Location : ")
download_location = input()
driver = webdriver.Chrome(chrome_driver_path, chrome_options=options)
print("Loading Comic...")
driver.get(album_url)
album_html = driver.page_source
print("Comic successfully loaded")
soup = BeautifulSoup(album_html,"lxml")
comic_name = soup.find("title").text.split("|")[0].strip()
download_location = os.path.join(download_location,comic_name)
os.mkdir(download_location)
print("Finding comic's pages")
images = soup.find_all("a",{"class":"c-tile t-hover"})
page_urls = []
pages = []
threads = []
for image in images:
page_urls.append(base_url + image['href'])
print("Found {} pages".format(len(page_urls)))
for i in range(len(page_urls)):
pages.append((page_urls[i],i,download_location))
p = Pool(3) # 3 threads in the pool
p.starmap(fetch_image_url,pages)
p.close()
p.join()
driver.quit()
print ("DONE ! Happy Reading ")项目Github:https://github.com/ggrievous/8muser
发布于 2019-04-29 04:01:22
没有理由在这里使用selenium。与其接触selenium,不如先尝试更简单的路径。在没有javascript的情况下加载页面,看看是否可以找到任何有用的信息,说明图像是如何到达那里的。一定有什么东西(也许是AJAX)可以为它们获取URL。他们不只是魔术般地出现!
事实证明,如果你这样做,你会发现没有任何花哨的JS东西。照片就在那里,就像这样:
<div class="image">
<img class="lazyload" data-src="/image/th/QD-H-4F3JpxykaxnIIFbrixlkt4rwBphjoSmX2E8fvoJ8JanT-+S2MdyjKTADNm+SJdCVhXQwkdIZ0tQel-n8-y70M9EOTmeW06uA5ubLwnl2gi5X14+yw6GKhNbhj7S.jpg">
</div>这意味着,您可以使用一行BeautifulSoup提取所有这些URL:
urls = [img['data-src'] for img in doc.find_all('img', class_='lazyload')]现在,关于您的代码的一些评论:
C:\Users\NH\PycharmProjects\SeleniumTest\drivers\chromedriver.exe上有一个硒驱动器?BeautifulSoup(page, 'html5lib')而不是lxml。image_url结构有点草率。通常,我们使用urllib.path来构建路径,而不是仅仅进行字符串连接。pathlib而不是os.path'Mozilla/5.0'不是一个会欺骗任何人的用户代理。如果你真的想躲在雷达下,就用一个真正的UAsleep()s。切断你的刮刀。threading在Python中有点没用。这在某种程度上是一个I/O绑定任务(线程非常适合这个任务),但是HTML解析和提取肯定可以与web请求同时进行(但是线程不允许这样做)。你几乎总是想要找到multiprocessing。close()和join():with Pool() as pool:
pool.imap_unorderd(fetch_image_url, pages)Pool传递参数。它默认为CPU核心的数量,这几乎总是您想要的。starmap被命令并阻塞。它只能按部就班地处理。在本例中,这是可以的,因为您实际上没有返回任何内容,但是如果您说在做数学时,您可能需要imap_unordered,它会在结果到达时产生结果(很可能是无序的)。print。您希望有一个进程写入stdout,否则您就可以编写争用(您可能不会遇到这种争用,因为您的字符串可能适合stdout缓冲区,但在某些情况下它们可能不适合)。但是,这一切最终导致了以下建议:不要使用Python下载东西!
特别是因为这种抓取看起来并不像库一样有用(相反,您似乎只是提供了一个CLI实用程序供人类下载这些东西)。考虑到这一点,不重新发明方向盘是更明智和安全的。有些工具已经很好地完成了这样的工作:即wget (看起来您在windows上,您可以而且应该使用Ubuntu子系统,其中包含wget)。wget特别适合这项工作,并具有大量的内置功能,这将对您非常有用。这包括:
所有这些都是您的脚本目前无法完成的事情。特别是,在python中这样做非常容易:
pages = download_hundreds_of_pages() # takes hours...
for page in paages: # oops, this NameErrors and you lose everything you've downloaded
pass这样的错误太容易犯了。您可以使用以下工作流完全避免它们:
wget -nc -i urls.txt下载对于您来说,这将涉及到一个包含图像的urls列表。那就做wget -nc -i pages.txt。它将将所有页面下载到当前目录。然后,您可以制作一个Python脚本,它使用漂亮的汤(和我前面提到的行)来提取图像urls:python3 extract_image_urls.py > image_urls.txt。然后下载它们做wget -nc -i image_urls.txt。如果您的python脚本在任何时候都失败了,那么您不会丢失已经完成的所有下载。您可以在一个方便的bash脚本中包装所有这些。
https://codereview.stackexchange.com/questions/219237
复制相似问题