当前位置:   article > 正文

python爬取有声小说网站实现自动下载实例_scrapy 爬取听书海洋

scrapy 爬取听书海洋

最近想下载一些有声小说,但是苦于没有找到批量下载,每次都是单集单集的下载的,觉得很麻烦,就考虑用python写一个爬虫来实现自动搜集小说,自动下载。下面就是开始展开漫漫的爬虫之路。

基础的就不多说了,重点就是针对在项目中遇见的一些问题进行记录。主要就以下三个方面进行展开:

1.正则表达式的使用

2.编码格式

3.如何获取js动态加载生成的内容

1.正则表达式的使用

正则表达式主要是用于匹配相应的标签,这个可以快速定位出需要的标签,使爬虫更有效率。

如:

考虑使用如下正则表达式:

self.down_pattern = '<a title=.+? href=(.\/down.+?)target=.*?>.+?</a>'

一开始编写正则的时候,主要是刚开始使用,很多不是很熟悉,使用了\w来匹配,后来发现无法匹配,后来换成了.来匹配,同时使用了非贪婪匹配。非贪婪匹配就是在*+后加上?即可。具体的正则表达式相关的知识请参阅别的教程,总之正则是个很大很大的坑,日后还有再找机会慢慢填。

2.编码格式

编码格式也是个很恼火的问题,在编写爬虫爬取网页经常爆出unicodeencodeerror错误,几乎都是中文导致的影响,所以每次以后记住,如果网页中有中文出现,返回的响应用decode('gbk')或者decode('gb2312')解码,这样中文就可以显示正确了。同时如果在url中出现了中文,那么想当然也要进行相应的编码,可以使用urllib.parse.quote()来进行相应编码,一般默认utf-8,但在运用听书网的搜索功能时,发现它传入的中文转换成了gb2312格式,那么只需quote传入gb2312就行。这里也是当时费了一点时间,所以提醒自己日后一定要注意多种格式编码。后来借助一个在线编码转换网站,成功发现了它是转换成了gb2312,之前都是默认用的utf-8。这里安利一下这个网站,感觉方便的。http://tool.chinaz.com/tools/urlencode.aspx

3.获取js动态生成的内容

在编写自动下载小说的过程中发现,当我访问每个下载链接的主页的时候,我爬取不到下载的url,咦,当时就觉得很奇怪,查看了源之后发现确实没有写在源中,于是猜测可能是动态加载了,好吧,那就乖乖打开开发人员工具吧。之前有过爬取豆瓣排行榜的经历,所以首先想到的是xhr类型,返回一个json格式数据,后来发现并不是,接着查看了网页加载后的所有动态文件,发现一个叫down.js的文件有点意思啊,查看了它的响应结果,果真,就是下载地址。好吧,那么问题就来了,如果使用python3来爬取js动态加载的内容呢。这里就最简单的考虑了使用selenium+edge来模拟浏览器访问,等加载完成之后,再读取相应地址。这里呢安装selenium还是挺简单的,顺带还要下载一个edge的运行驱动吧,把驱动放在一个配置了path的目录下,这样似乎才可以正确调用浏览器。后面还要继续在学下selenium。

下面是全部代码:

  1. import urllib.request
  2. import urllib.parse
  3. import re
  4. import os.path
  5. import selenium.webdriver
  6. # <a title="第000章" href="/down/?26-0-0.html" target="_blank">第000章</a>
  7. class TingSpider:
  8. def __init__(self, bookname):
  9. self.down_pattern = '<a title=.+? href=(.\/down.+?) target=.*?>.+?</a>' # 匹配下载主页
  10. self.pattern = '<a title=.+? href=.+? target=.*?>(.+?)</a>' # 匹配章节名称
  11. self.hotpattern = '<a href=(.*?) title=.*>.*</a></h2>(\d*?)<b>' # 匹配书的热度的正则表达
  12. self.index_url = "http://www.520tingshu.com/search.asp?searchword=" # 搜索主页
  13. self.down_url_pattern = '<a href=(.+)\/.*\.mp3" target=.*?>.+?</a>' # 下载链接的地址
  14. self.bookname = bookname
  15. def __getmax(self, result): # 获取搜索的结果中热度最高的那本书
  16. max_item = None
  17. for i in range(len(result)):
  18. if max_item == None:
  19. max_item = result[i]
  20. elif int(result[i][1]) > int(max_item[1]):
  21. max_item = result[i]
  22. return max_item
  23. def __searchbook(self): # 获得要搜索的书的首页地址
  24. file = urllib.request.urlopen(self.index_url + urllib.parse.quote(self.bookname, encoding='gb2312'))
  25. data = file.read().decode('gbk')
  26. result = re.findall(self.hotpattern, data)
  27. if result is None:
  28. raise 'No book found'
  29. res = self.__getmax(result)
  30. new_url = "http://www.520tingshu.com"+res[0].replace('"', '')
  31. return new_url
  32. def __getlist(self): # 获得该有声小说所有的章节名,小说下载页的url
  33. bookurl = self.__searchbook()
  34. req = urllib.request.Request(bookurl)
  35. file = urllib.request.urlopen(req)
  36. data = file.read().decode('gbk')
  37. result = re.findall(self.pattern, data)
  38. tmp_url = re.search(self.down_pattern, data)
  39. return result, "http://www.520tingshu.com" + tmp_url.group(1).replace("'", '')
  40. def __getdownurl(self, downpage): # 获取下载链接地址的除去文件名的地址
  41. brower = selenium.webdriver.Edge()
  42. brower.get(downpage)
  43. brower.maximize_window()
  44. result = re.search(self.down_url_pattern, brower.page_source)
  45. brower.close()
  46. return result.group(1).replace('"', '') + '/'
  47. def __getAllUrl(self): # 获得所有的章节的下载地址
  48. url = []
  49. result, downpage = self.__getlist()
  50. down_url = self.__getdownurl(downpage)
  51. for item in result:
  52. tmp_url = down_url + item + ".mp3"
  53. url.append(urllib.request.quote(tmp_url, safe='/:?='))
  54. return url
  55. def down_file(self):
  56. result = self.__getAllUrl() # 所有的章节对应的下载地址
  57. for i in range(len(result)):
  58. s = str(i)+".mp3"
  59. if self.__exist(s) == False:
  60. self.__downfile(result[i], s)
  61. def __downfile(self, url, filename): # 将文件下载到本地
  62. file = urllib.request.urlopen(url)
  63. data = file.read()
  64. with open(filename, "wb") as f:
  65. f.write(data)
  66. def __exist(self, s):
  67. if os.path.exists(s):
  68. return True
  69. else:
  70. return False
  71. test = TingSpider("诛仙")
  72. test.down_file()
代码地址:https://github.com/xiaoHzp/python/blob/master/Ting_shu.py
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/961574
推荐阅读
相关标签
  

闽ICP备14008679号