翼度科技»论坛 编程开发 python 查看内容

使用playwright爬取魔笔小说网站并下载轻小说资源

3

主题

3

帖子

9

积分

新手上路

Rank: 1

积分
9
一、安装python

官网
下载python3.9及以上版本
二、安装playwright

playwright是微软公司2020年初发布的新一代自动化测试工具,相较于目前最常用的Selenium,它仅用一个API即可自动执行Chromium、Firefox、WebKit等主流浏览器自动化操作。
(1)安装Playwright依赖库
  1. 1 pip install playwright
复制代码
 
(2)安装Chromium、Firefox、WebKit等浏览器的驱动文件(内置浏览器)
  1. 1 python -m playwright install
复制代码
三、分析网站的HTML结构

魔笔小说网是一个轻小说下载网站,提供了mobi、epub等格式小说资源,美中不足的是,需要跳转城通网盘下载,无会员情况下被限速且同一时间只允许一个下载任务。
当使用chrome浏览器时点击键盘的F12进入开发者模式。
(一)小说目录


HTML内容



通过href标签可以获得每本小说的详细地址,随后打开该地址获取章节下载地址。
(二)章节下载目录


HTML内容


遍历每本小说的地址并保存到单独的txt文件中供后续下载。
(三)代码
  1. 1 import time,re
  2. 2
  3. 3 from playwright.sync_api import Playwright, sync_playwright, expect
  4. 4
  5. 5 def cancel_request(route,request):
  6. 6     route.abort()
  7. 7 def run(playwright: Playwright) -> None:
  8. 8     browser = playwright.chromium.launch(headless=False)
  9. 9     context = browser.new_context()
  10. 10     page = context.new_page()
  11. 11     # 不加载图片
  12. 12     # page.route(re.compile(r"(\.png)|(\.jpg)"), cancel_request)
  13. 13     page.goto("https://mobinovels.com/")
  14. 14     # 由于魔笔小说首页是动态加载列表,因此在此处加30s延迟,需手动滑动页面至底部直至加载完全部内容
  15. 15     for i in range(30):
  16. 16         time.sleep(1)
  17. 17         print(i)
  18. 18     # 定位至列表元素
  19. 19     novel_list = page.locator('[]')
  20. 20     # 统计小说数量
  21. 21     total = novel_list.count()
  22. 22     # 遍历获取小说详情地址
  23. 23     for i in range(total):
  24. 24         novel = novel_list.nth(i).locator("a")
  25. 25         title = novel.inner_text()
  26. 26         title_url = novel.get_attribute("href")
  27. 27         page1 = context.new_page()
  28. 28         page1.goto(title_url,wait_until='domcontentloaded')
  29. 29         print(i+1,total,title)
  30. 30         try:
  31. 31             content_list = page1.locator("table>tbody>tr")
  32. 32             # 保存至单独txt文件中供后续下载
  33. 33             with open('./novelurl/'+title+'.txt', 'a') as f:
  34. 34                 for j in range(content_list.count()):
  35. 35                     if content_list.nth(j).locator("td").count() > 2:
  36. 36                         content_href = content_list.nth(j).locator("td").nth(3).locator("a").get_attribute("href")
  37. 37                         f.write(title+str(j+1)+'分割'+content_href + '\n')
  38. 38         except:
  39. 39             pass
  40. 40         page1.close()
  41. 41     # 程序结束后手动关闭程序
  42. 42     time.sleep(50000)
  43. 43     page.close()
  44. 44
  45. 45     # ---------------------
  46. 46     context.close()
  47. 47     browser.close()
  48. 48
  49. 49
  50. 50 with sync_playwright() as playwright:
  51. 51     run(playwright)
复制代码
(四)运行结果



四、开始下载

之所以先将下载地址保存到txt再下载而不是立即下载,是防止程序因网络等原因异常崩溃后记录进度,下次启动避免重复下载。
(一)获取cookies

城通网盘下载较大资源时需要登陆,有的轻小说文件较大时,页面会跳转到登陆页面导致程序卡住,因此需利用cookies保存登陆状态,或增加延迟手动在页面登陆。
chrome浏览器可以通过cookies editor插件获取cookies,导出后即可使用。
(二)分析下载地址

下载地址有三种类型,根据判断条件分别处理:
(1)文件的访问密码统一为6195,当域名为 https://url74.ctfile.com/ 地址后缀带有 ?p=6195 时,页面自动填入访问密码,我们需要在脚本中判断后缀是否为 ?p=6195 ,如不是则拼接字符串后访问;
(2)有后缀时无需处理;
(3)当域名为 https://t00y.com/ 时无需密码;
  1. 1                         if "t00y.com" in new_url:
  2. 2                             page.goto(new_url)
  3. 3                         elif "?p=6195" not in new_url:
  4. 4                             page.goto(new_url+"?p=6195")
  5. 5                             page.get_by_placeholder("文件访问密码").click()
  6. 6                             page.get_by_role("button", name="解密文件").click()
  7. 7                         else:
  8. 8                             page.goto(new_url)
  9. 9                             page.get_by_placeholder("文件访问密码").click()
  10. 10                             page.get_by_role("button", name="解密文件").click()
复制代码
(三)开始下载

playWright下载资源需利用 page.expect_download 函数。
下载完整代码如下:
  1. 1 import time,os
  2. 2
  3. 3 from playwright.sync_api import Playwright, sync_playwright, expect
  4. 4
  5. 5
  6. 6 def run(playwright: Playwright) -> None:
  7. 7     browser = playwright.chromium.launch(channel="chrome", headless=False) # 此处使用的是本地chrome浏览器
  8. 8     context = browser.new_context()
  9. 9     path = r'D:\PycharmProjects\wxauto\novelurl'
  10. 10     dir_list = os.listdir(path)
  11. 11     # 使用cookies
  12. 12     # cookies = []
  13. 13     # context.add_cookies(cookies)
  14. 14     page = context.new_page()
  15. 15     for i in range(len(dir_list)):
  16. 16         try:
  17. 17             novel_url = os.path.join(path, dir_list[i])
  18. 18             print(novel_url)
  19. 19             with open(novel_url) as f:
  20. 20                     for j in f.readlines():
  21. 21                         new_name,new_url = j.strip().split("分割")
  22. 22                         if "t00y.com" in new_url:
  23. 23                             page.goto(new_url)
  24. 24                         elif "?p=6195" not in new_url:
  25. 25                             page.goto(new_url+"?p=6195")
  26. 26                             page.get_by_placeholder("文件访问密码").click()
  27. 27                             page.get_by_role("button", name="解密文件").click()
  28. 28                         else:
  29. 29                             page.goto(new_url)
  30. 30                             page.get_by_placeholder("文件访问密码").click()
  31. 31                             page.get_by_role("button", name="解密文件").click()
  32. 32
  33. 33                         with page.expect_download(timeout=100000) as download_info:
  34. 34                             page.get_by_role("button", name="立即下载").first.click()
  35. 35                             print(new_name,"开始下载")
  36. 36                         download_file = download_info.value
  37. 37                         download_file.save_as("./novel/"+dir_list[i][:-4]+"/"+download_file.suggested_filename)
  38. 38                         time.sleep(3)
  39. 39             os.remove(novel_url)
  40. 40             print(i+1,dir_list[i],"下载结束")
  41. 41         except:
  42. 42             print(novel_url,"出错")
  43. 43     time.sleep(60)
  44. 44     page.close()
  45. 45
  46. 46     # ---------------------
  47. 47     context.close()
  48. 48     browser.close()
  49. 49
  50. 50
  51. 51 with sync_playwright() as playwright:
  52. 52     run(playwright)
复制代码
(四)运行结果


 
TRANSLATE with
<img id="FloaterLogo">
x  English
ArabicHebrewPolish
BulgarianHindiPortuguese
CatalanHmong DawRomanian
Chinese SimplifiedHungarianRussian
Chinese TraditionalIndonesianSlovak
CzechItalianSlovenian
DanishJapaneseSpanish
DutchKlingonSwedish
EnglishKoreanThai
EstonianLatvianTurkish
FinnishLithuanianUkrainian
FrenchMalayUrdu
GermanMalteseVietnamese
GreekNorwegianWelsh
Haitian CreolePersian 
<img alt="" >
   
<img id="HelpImg">
<img id="EmbedImg">
<img id="ShareImg">
     TRANSLATE with
<img id="CollapsedLogoImg">
  COPY THE URL BELOW      
<img id="EmailImg">
   
<img id="ShareHelpImg">
Back      EMBED THE SNIPPET BELOW IN YOUR SITE  
<img id="EmbedHelpImg">
   Enable collaborative features and customize widget: Bing Webmaster PortalBack
来源:https://www.cnblogs.com/xwjz/p/17752999.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具