django+vue+nginx+frp搭建漫画网站之爬虫部分新增站点漫画狂cartoonmad(四)

本文介绍了使用Python Scrapy和Requests库爬取漫画网站CartoonMad的过程,包括获取最大漫画ID、漫画详情页信息、章节信息和图片信息。强调了遵循robots协议的重要性,以及如何通过XPath提取所需数据。还分享了爬取频率设置的建议,以降低服务器压力和提高爬取效率。
摘要由CSDN通过智能技术生成

地址:http://www.iewoai.com/

背景

1、背景

看了下记录,已经有一个月没有新增爬虫站点了,懈怠了懈怠了/抱头。

image.png

这次要整的网站是http://www.cartoonmad.com,漫画数目不多,在一万以下,属于比较简单的网站。貌似是使用ASP(Active Server Pages 动态服务器页面)写的,详情可以查看[1],是许多年前语言了,但问题不大,只要能看到就能爬。网站也是老牌网站(据说),有些是目前vomic漫画上没有的,资源质量也还不错。只是页面加载慢和网页结构比较不规范,但这并不影响爬虫的编写。

2、步骤

爬虫主要使用python的scrapy和requests库,由于是第八个爬取的漫画站点了,早已有了一套爬取流程。主要流程为:找最大id、详情页、章节信息、图片信息。

0、首先查看robots协议(没有,过)

如果有的话,还是建议爬取别人站点时遵循robots协议的内容,合理设置请求频率和爬取页面,做一个友好的爬虫~~(如果有sitemap等地址的话,也有利于分析页面)~~

1、寻找最大id

为了减轻爬虫逻辑,最好的办法就是找规律,比如找到爬取页的最大id、列表页最大页数、接口参数的最大值。漫画详情页地址为:https://www.cartoonmad.com/comic/5292.html5292就是该漫画的id了,那只需找到最大id即可。一般站点会有最新上架的漫画页面,这个站点也不例外:https://www.cartoonmad.com/comic99.html,第一个就是最新的漫画,max_id为8783

image_1.png]

编写获取max_id的代码如下:

  # 获取最新的漫画id
  def get_max_id(self):
      url = 'https://www.cartoonmad.com/comic99.html'
      r = requests.get(url)
      r.encoding = r.apparent_encoding
      temp = etree.HTML(r.text).xpath('//a[@class="a1"]/@href')[0]
      max_id = re.findall(r'\d+', temp)[0]
      return int(max_id) 

并编写start_requests函数:

  def start_requests(self):
      max_id = self.get_max_id()
      while max_id >= 0:
          comic_id = max_id
          url = f'https://www.cartoonmad.com/comic/{max_id}.html'
          print(f'正在爬取[{url}]')
          yield scrapy.Request(url, callback=self.parse_main, meta={'comic_id': str(comic_id)})
          max_id -= 1

2、详情页信息

image_2.png

漫画主要采集的包括:标题,简介,关键,分类,作者名称等

页面结构清晰,但是dom树比较糟糕,使用xpath提取时用了不少的contains(只贴出xpath,其他处理参考完整代码):

  • 标题://*[contains(text(), "簡介")]/text()

  • 简介://*[contains(text(), "簡介")]/..//td//text()

  • 关键字://*[contains(@href, "/tag.asp")]/text()

  • 分类://*[contains(text(), "漫畫分類")]/..//a/text()

  • 作者名称://*[contains(text(), "原創作者:")]/text()

  • 星级://span[contains(@class, "vstar")]/@class

  • 封面图://*[@class="cover"]/../img/@src

全部信息如下:

image_6.png

3、章节信息

主要采集章节名称,图片数目,章节下标,是否更新主表(只有在最新一章节的时候采需要更新到主表里去)等,这部分也同样是xpath,具体不再赘述,详情参考完整代码。不过部分页面上显示的章节信息并不完整。

4、图片信息

这个站点的图片信息比较简单,没有接口也没有什么反爬。不过图片是通过重定向获取到真实地址的,且一页只有一张图片,且手机端也是,还有广告(体验极差),但还是能通过获取最大页码去拼接图片地址的方式得到所有的真实页图片地址。这样从详情页进来爬取完一个章节的所有图片,只需要请求三次即可:详情业+章节页 + 重定向。

再次建议编写爬虫时,尽量减少请求的次数,这样可以降低被爬取方的服务器压力和提升爬取方的爬取效率

image_4.png]

先获取第一张图的src和总页数:

  first_src = self.vcrawl('//img[contains(@src, "?file=")]/@src', response)
  page_all = response.xpath('//select/option/text()').extract()
  if first_src and page_all:
      page_all = re.findall(r'\d+', page_all[-1])
      if page_all:
          meta['page_all'] = int(page_all[0])
          # print(first_src)
          yield scrapy.Request(first_src, callback=self.parse_page, meta=meta)

构造请求,并在parse_page中获取到重定向之后的real_src,并拼接出所有图片地址:

page_all = response.meta['page_all']
real_src = response.url
real_src_head = real_src.rsplit('/', 1)[0]
real_src_end = real_src.rsplit('/', 1)[-1].split('.')[-1]

for i in range(1, page_all+1):
    sort_index = i
    page_url = f'{real_src_head}/{i:03}.{real_src_end}'

部分结果如下:

image_5.png

image_6.png

到此爬取结束。

3、总结

像此类小众网站一般不会有反爬措施,而且数据量小,基本能找到构造url或者图片地址的办法。但还是要注意爬取频率,我一般都会在各站点的爬虫中指定爬取频率,类似:

  custom_settings = {
      'RANDOMIZE_DOWNLOAD_DELAY': True,
      'DOWNLOAD_DELAY': 1,
  }

且行且珍惜,下一站爬取动漫屋:http://www.dm5.com/manhua-list-pay0/

参考资料:

  1. ASP 简介 https://www.w3school.com.cn/asp/asp_intro.asp
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值