Python 爬虫 携程池 爬取腾讯动漫

简介

主要爬取腾讯动漫上某一漫画的所有图片的url

  • 所用到的库
  • 分析腾讯动漫网址
  • 代码

所用到的库

  • gevent gevent.pool
  • requests
  • selenium
  • xpath

分析腾讯动漫

就以我是大神仙这一免费漫画为例,分析其标签。 url地址为 ac.qq.com/Comic/Comic…

  • 获取漫画章节url
    621058 表示漫画的代码
    #获取列表 
    el.xpath('//*[@id="chapter"]/div[2]/ol[1]/li')
    # 判断过滤不需要的章节
    startswith(('第', '序'))
    #将获得的章节存储在队列中
    list_url.append(item)
    self.queue.put(item)
复制代码
  • 获取漫画章节详情

第 111 话 ac.qq.com/ComicView/i…

两种方法获取列表图片url

  • 第一种通过selenium 模拟浏览器滑动来获取真实的url,这种方法比较慢,有时候有些图片可能因为滑动太快url地址加载不出来。当然可以设置滑动时间保证都能获取得到
browser.get('http://ac.qq.com/ComicView/index/id/621058/cid/122')
for i in range(10):
    js = 'window.scrollTo(' + str(i * 1280) + ',' + str((i + 1) * 1280) + ')'  # 把内容滚动到指定的坐标
    browser.execute_script(js)
    time.sleep(1)
复制代码
  • 第二种分析网页滑动过程中加载的js
    已经分析出来在 其实imgurl 在页面加载时就已经有 只不过是保存在DATA中需要解密
    网页中 script 标签中有var DATA ="" 很长的字符串 这个需要解密 解密的js函数我们其实不需要知道
复制代码

我们可以在浏览器控制台上打印出来DATA 的值如下 这样就获取的所有的url了 
复制代码

 那我们怎么获取DATA熟悉呢?其实不用获取DATA 只需要获取PICTURE这个就好了
 如果不用selenium 那需要解密var DATA 这个就比较麻烦了 所以还是用selenium吧
     def get_img_list(self, html_str):
        browser = self.webdirver(html_str)
        list_tmp = []
        # selenium 通过执行return 返回变量的值
        pic_list = browser.execute_script("return PICTURE")
        for pic in pic_list:
            item = {}
            item['href'] = pic['url']
            list_tmp.append(item)
        browser.quit()
        return list_tmp
复制代码

代码

import gevent.monkey
gevent.monkey.patch_all()

import json
import time
from queue import Queue

import os
import requests
from gevent.pool import Pool
from lxml import etree
from pymongo import MongoClient

from selenium import webdriver

"""
多线程爬取
腾讯动漫
1.获取 动漫url
2.获取 章节url
3.获取 图片url
"""
class TencentCarton(object):

    def __init__(self):
        self.start_url = "http://ac.qq.com/Comic/ComicInfo/id/621058"
        self.headers = {
            "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/66.0.3359.139 Safari/537.36"
        }
        self.part_url = "http://ac.qq.com"
        self.queue = Queue()
        self.pool = Pool(5)
        self.is_running = True
        self.total_request_num = 0
        self.total_response_num = 0
        self.str_ss = "./我是大神仙/"

    def get_url_list(self):
        html = self.parse_url(self.start_url)
        el = etree.HTML(html)
        li_list = el.xpath('//*[@id="chapter"]/div[2]/ol[1]/li')
        list_url = []
        for li in li_list:
            for p in li.xpath("./p"):
                for span in p.xpath("./span[@class='works-chapter-item']"):
                    item = {}
                    list_title = span.xpath("./a/@title")[0].replace(' ', '').split(':')
                    if list_title[1].startswith(('第', '序')):
                        item['name'] = list_title[1]
                        item['href'] = self.part_url + span.xpath("./a/@href")[0]
                        item['title'] = list_title[0]
                        list_url.append(item)
                        self.queue.put(item)
                        self.total_request_num += 1

    def parse_url(self, url):
        res = requests.get(url, headers=self.headers)
        return res.content.decode()

    def webdirver(self, html_str):
        chrome_options = webdriver.ChromeOptions()
        chrome_options.add_argument('--headless')
        browser = webdriver.Chrome(chrome_options=chrome_options)
        # 上面三行代码表示可以无界面爬取
        browser.get(html_str)
        return browser

    def get_img_list(self, html_str):
        browser = self.webdirver(html_str)
        list_tmp = []
        pic_list = browser.execute_script("return PICTURE")
        for pic in pic_list:
            item = {}
            item['href'] = pic['url']
            list_tmp.append(item)
        browser.quit()
        return list_tmp

    def save_content_list(self, data):
        json_str = json.dumps(data, ensure_ascii=False, indent=2)
        if not os.path.exists(self.str_ss):
            os.mkdir(self.str_ss)
        with open(self.str_ss + data['name'] + ".json", 'w', encoding='utf-8') as f:
            f.write(json_str)
        print(data['name'], "保存成功")

    def _execete_request_content_save(self):
        item = self.queue.get()
        print(item['href'], "开始请求")
        try:
            item['imge_list'] = self.get_img_list(item['href'])
        except Exception as f:
            print(f)
        # 保存
        self.save_content_list(item)
        self.total_response_num += 1

    def _callback(self, temp):
        if self.is_running:
            self.pool.apply_async(self._execete_request_content_save, callback=self._callback)

    def run(self):
        # 1. 准备url列表
        self.get_url_list()
        print(self.queue.qsize())
        for i in range(3):  # 设置并发数为3
            self.pool.apply_async(self._execete_request_content_save, callback=self._callback)

        while True:
            time.sleep(0.0001)
            if self.total_response_num >= self.total_request_num:
                self.is_running = False
                break


if __name__ == '__main__':
    t1 = time.time()
    TC = TencentCarton()
    TC.run()
    print("total cost:", time.time() - t1)

复制代码

你可能感兴趣的:(Python 爬虫 携程池 爬取腾讯动漫)