基于Scrapy的全球最大成人网站PornHub爬虫

2018-04-04 14:02:01 浏览数 (1)

首先科普下 PornHub 是个啥?

Pornhub是一个加拿大的色情影片分享网站。它是目前网上最大的色情影片网站,服务分享遍及全球。Pornhub于2007年在魁北克省蒙特利尔市成立。它是一个免费的,由广告支持的网站。除了专业色情内容,网站也提供业余色情内容。Pornhub在英国伦敦市,美国加利福尼亚州旧金山市,美国得克萨斯州休斯敦市以及美国路易斯安那州新奥尔良市均有分部和服务器。 2010年3月Pornhub被MindGeek购买,MindGeek同时拥有许多其他的色情网站。

声明:本项目旨在学习Scrapy爬虫框架和MongoDB数据库,不可使用于商业和个人其他意图。若使用不当,均由个人承担。

  • 项目主要是爬取全球最大成人网站PornHub的视频标题、时长、mp4链接、封面URL和具体的PornHub链接
  • 项目爬的是PornHub.com (需要访问外国网站),结构简单,速度飞快
  • 爬取PornHub视频的速度可以达到500万/天以上。具体视个人网络情况,因为我是家庭网络,所以相对慢一点。
  • 10个线程同时请求,可达到如上速度。若个人网络环境更好,可启动更多线程来请求,具体配置方法见 [启动前配置]
  • start_requests 根据 PorbHub 的分类,启动了5个Request,同时对五个分类进行爬取。
  • 并支持分页爬取数据,并加入到待爬队列。

环境

开发语言: Python2.7

开发环境: MacOS系统、4G内存

数据库: mongodb

  • 主要使用 scrapy 爬虫框架
  • 从Cookie池和UA池中随机抽取一个加入到Spider
  • start_requests 根据 PorbHub 的分类,启动了5个Request,同时对五个分类进行爬取。
  • 并支持分页爬取数据,并加入到待爬队列。

使用说明

  • 安装Scrapy
  • 安装Python的依赖模块:pymongo、json、requests
  • 根据自己需要修改 Scrapy 中关于 间隔时间、启动Requests线程数等得配置

启动

代码语言:javascript复制
python PornHub/quickstart.py

数据库说明

数据库中保存数据的表是 PhRes。以下是字段说明:

PhRes 表:

代码语言:javascript复制
video_title:视频的标题,并作为唯一标识.
link_url:视频调转到PornHub的链接
image_url:视频的封面链接
video_duration:视频的时长,以 s 为单位
quality_480p: 视频480p的 mp4 下载地址

主程序

代码语言:javascript复制
#coding:utf-8

import requests
import logging
from scrapy.spider import CrawlSpider
from scrapy.selector import Selector
from PornHub.items import PornVideoItem
from PornHub.pornhub_type import PH_TYPES
from scrapy.http import Request
import re
import json
import random

class Spider(CrawlSpider):
    name = 'pornHubSpider'
    host = 'https://www.pornhub.com/'
    start_urls = list(set(PH_TYPES))
    logging.getLogger("requests").setLevel(logging.WARNING
                                          )  # 将requests的日志级别设成WARNING
    logging.basicConfig(
        level=logging.DEBUG,
        format=        '%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
        datefmt='%a, %d %b %Y %H:%M:%S',
        filename='cataline.log',
        filemode='w')   

     # test = True
    def start_requests(self):
        for ph_type in self.start_urls:
                 yield Request(url='https://www.pornhub.com/%s' % ph_type,
                          callback=self.parse_ph_key) 
                 
    def parse_ph_key(self, response):
        selector = Selector(response)
        logging.debug('request url:------>'   response.url)     
        # logging.info(selector)
        divs = selector.xpath('//div[@class="phimage"]')        
        for div in divs:
            viewkey = re.findall('viewkey=(.*?)"', div.extract())            # logging.debug(viewkey)
            yield Request(url='https://www.pornhub.com/embed/%s' % viewkey[0],
                          callback=self.parse_ph_info)
        url_next = selector.xpath(            '//a[@class="orangeButton" and text()="Next "]/@href').extract()
        logging.debug(url_next)        
        if url_next:            
              # if self.test:
            logging.debug(' next page:---------->'   self.host   url_next[0])            
              yield Request(url=self.host   url_next[0],
                          callback=self.parse_ph_key)         
              # self.test = False


    def parse_ph_info(self, response):
        phItem = PornVideoItem()
        selector = Selector(response)
        _ph_info = re.findall('flashvars_.*?=(.*?);n', selector.extract())
        logging.debug('PH信息的JSON:')
        logging.debug(_ph_info)
        _ph_info_json = json.loads(_ph_info[0])
        duration = _ph_info_json.get('video_duration')
        phItem['video_duration'] = duration
        title = _ph_info_json.get('video_title')
        phItem['video_title'] = title
        image_url = _ph_info_json.get('image_url')
        phItem['image_url'] = image_url
        link_url = _ph_info_json.get('link_url')
        phItem['link_url'] = link_url
        quality_480p = _ph_info_json.get('quality_480p')
        phItem['quality_480p'] = quality_480p
        logging.info('duration:'   duration   ' title:'   title   ' image_url:'
                       image_url   ' link_url:'   link_url)        
        yield phItem

0 人点赞