pyspider简介

PySpider:一个国人编写的强大的网络爬虫系统并带有强大的WebUI。采用Python语言编写,分布式架构,支持多种数据库后端,强大的WebUI支持脚本编辑器,任务监视器,项目管理器以及结果查看器。在线示例:http://demo.pyspider .org/,学习教程:http://www.pyspider.cn/page/1.html

项目需求:

爬去 http://www.adquan.com/ 上面的文章供公司内部学习

简单实现,初步版(命名规范忽略):

# -*- coding: utf-8 -*-
#__author:jiangjing
#date:2018/2/2
# !/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created on 2017-12-07 13:40:43
# Project: adquan from pyspider.libs.base_handler import *
import os
import urlparse
import datetime
import re
import requests
import uuid UPLOAD_IMAGE_URL = "http://10.32.64.194:8233/api/NoLogin/UploadImage" #上传图片至目标服务器
ADD_WEIBO_ARTICLE_URL = "http://10.32.64.194:8233/api/NoLogin/AddDraft" #把当前文章添加到草稿
WEIBO_IMAGE_URL = "/upload/image" #地址拼接用
PLAY_VIDEO_URL = "http://10.32.64.196:10001/hls/video/catch" #播放视频的地址
IMAGE_DIR_PATH = "/var/hls/image/catch" #图片存放地址
VIDEO_DIR_PATH = "/var/hls/video/catch" #视频存放地址 class Handler(BaseHandler):
crawl_config = {
} def __init__(self):
self.deal = Deal() @every(minutes=24 * 60 * 3)
def on_start(self):
self.crawl('http://www.adquan.com', callback=self.index_page) @config(age=100 * 24 * 60 * 60)
def index_page(self, response):
for each in response.doc('.work_list_left .w_l_inner_img a').items():
self.crawl(each.attr.href, callback=self.detail_page) @config(priority=2)
def detail_page(self, response):
today_str = datetime.date.today().strftime("%Y-%m-%d")
# 抓取封面
cover_guid = ''
for img in response.doc('.con_pic_title img').items():
url = img.attr.src
if url:
image_path = self.deal.getImageDirPath()
extension = self.deal.getExtension(url)
guid = str(uuid.uuid1()).replace('-', '')
file_name = "origin_" + guid + '.' + extension
file_path = image_path + '/' + file_name
content = requests.get(url).content
self.deal.saveImg(content, file_path)
self.upload_image_to_weibo(file_path, guid, file_name)
cover_guid = guid # 爬取图片
for img in response.doc('.con_Text img').items():
url = img.attr.src
if url:
extension = self.deal.getExtension(url)
guid = str(uuid.uuid1()).replace('-', '')
file_name = "origin_" + guid + '.' + extension
self.crawl(img.attr.src, callback=self.save_img, save={'file_name': file_name, 'guid': guid})
img.attr.src = '%s/%s/%s' % (WEIBO_IMAGE_URL, datetime.date.today().strftime("%Y%m%d"), file_name)
# 抓取视频
for video in response.doc('.con_Text iframe').items():
width = video.attr.width
if not width:
width = 600
iframe_url = str(video.attr('data-src')).strip()
if not video.attr('data-src'):
iframe_url = str(video.attr.src).strip()
if not iframe_url:
continue
ret = urlparse.urlparse(iframe_url)
vids = re.findall('vid=(\d|\w*)&?', ret.query)
if not vids or not vids[0].strip():
logger.error("get video id failed, url:%s" % (url))
continue
guid = str(uuid.uuid1()).replace('-', '')
play_url = '%s/%s/%s.mp4' % (PLAY_VIDEO_URL, today_str, guid)
cover_img= '%s/%s/%s.jpg' % (PLAY_VIDEO_URL, today_str, guid)
video.replaceWith('<video controls="1" src=%s width=%s poster=%s></video>' % (play_url, str(width), cover_img))
video.attr.poster = cover_img
self.download_video(vids[0].strip(), guid)
if response.doc('.text_title').text() != '':
html_content = response.doc('.con_Text').html()
text_content = self.deal.filterTag(html_content)
self.add_article_to_weibo(response.doc('.text_title').text(), html_content , text_content, 2,
cover_guid) def add_article_to_weibo(self, title, content, contentText, articleType, picguid):
data = {'title': title, "content": content, "contentText": contentText, "articleType": articleType,
"picguid": picguid}
response = requests.post(ADD_WEIBO_ARTICLE_URL, data=data)
return {
"add_article_to_weibo": response.text
} def download_video(self, vid, guid):
data = {
"otype": "xml",
"platform": 11,
"format": 2,
"vid": vid,
"filename": "1.mp4",
"appver": '3.2.19.333'
}
vurl = 'http://vv.video.qq.com/getkey';
try:
response = requests.post('http://vv.video.qq.com/getkey', data=data)
keys = re.findall('<key>([\s\S]+?)</key>', response.text)
if len(keys) != 0:
video_url = 'http://videohy.tc.qq.com/video.dispatch.tc.qq.com/%s.mp4?vkey=%s&ocid=2692093356' % (
vid, keys[0].strip())
ext = ".mp4"
ret = urlparse.urlsplit(video_url)
items = ret.path.split('/')
today_str = datetime.date.today().strftime("%Y-%m-%d")
if items[-1]:
idx = items[-1].find(".")
ext = items[-1][idx:]
response = requests.get(video_url)
self.save_vedio(response.content, guid)
finally:
pass def save_img(self, response):
content = response.content
image_path = self.deal.getImageDirPath()
file_name = response.save['file_name']
guid = response.save['guid']
file_path = image_path + '/' + file_name
self.deal.saveImg(content, file_path)
self.upload_image_to_weibo(file_path, guid, file_name) def upload_image_to_weibo(self, file_path, guid, file_name):
data = {'guid': guid, "fileName": file_name}
files = {'file': open(file_path, 'rb')}
response = requests.post(UPLOAD_IMAGE_URL, data=data, files=files)
return {
"upload_image": response.text
} def save_vedio(self, content, guid):
import threading
ext = ".mp4"
file_name = guid + ext
video_path = self.deal.getVideoDirPath()
file_path = video_path + '/' + file_name
self.deal.saveVedio(content, file_path)
os.system('ffmpeg -i %s -y -f image2 -ss 1 -vframes 1 %s' % (file_path, file_path.replace('.mp4', '.jpg'))) def cut_video(self, shell):
os.system(shell) class Deal:
def __init__(self):
today_str = datetime.date.today().strftime("%Y-%m-%d")
self.mkDir('%s/%s' % (IMAGE_DIR_PATH, today_str))
self.mkDir('%s/%s' % (VIDEO_DIR_PATH, today_str)) def getImageDirPath(self):
today_str = datetime.date.today().strftime("%Y-%m-%d")
return '%s/%s' % (IMAGE_DIR_PATH, today_str); def getVideoDirPath(self):
today_str = datetime.date.today().strftime("%Y-%m-%d")
return '%s/%s' % (VIDEO_DIR_PATH, today_str); def mkDir(self, path):
path = path.strip()
exists = os.path.exists(path)
if not exists:
os.makedirs(path)
return path
else:
return path def saveImg(self, content, path):
f = open(path, 'wb')
f.write(content)
f.close() def saveVedio(self, content, path):
f = open(path, 'wb')
f.write(content)
f.close() def getExtension(self, url):
extension = url.split('.')[-1]
return extension #将HTML中标签等信息去掉
#@param htmlstr HTML字符串.'''
def filterTag(self, htmlstr):
re_cdata = re.compile('<!DOCTYPE HTML PUBLIC[^>]*>', re.I)
re_script = re.compile('<\s*script[^>]*>[^<]*<\s*/\s*script\s*>', re.I) #过滤脚本
re_style = re.compile('<\s*style[^>]*>[^<]*<\s*/\s*style\s*>', re.I) #过滤style
re_br = re.compile('<br\s*?/?>')
re_h = re.compile('</?\w+[^>]*>')
re_comment = re.compile('<!--[\s\S]*-->')
s = re_cdata.sub('', htmlstr)
s = re_script.sub('', s)
s=re_style.sub('',s)
s=re_br.sub('\n',s)
s=re_h.sub(' ',s)
s=re_comment.sub('',s)
blank_line=re.compile('\n+')
s=blank_line.sub('\n',s)
s=re.sub('\s+',' ',s)
s=self.replaceCharEntity(s)
return s '''##替换常用HTML字符实体.
#使用正常的字符替换HTML中特殊的字符实体.
#你可以添加新的实体字符到CHAR_ENTITIES中,处理更多HTML字符实体.
#@param htmlstr HTML字符串.'''
def replaceCharEntity(self, htmlstr):
CHAR_ENTITIES={'nbsp':'','':'',
'lt':'<','':'<',
'gt':'>','':'>',
'amp':'&','':'&',
'quot':'"''"','':'"'}
re_charEntity=re.compile(r'&#?(?P<name>\w+);') #命名组,把 匹配字段中\w+的部分命名为name,可以用group函数获取
sz=re_charEntity.search(htmlstr)
while sz:
#entity=sz.group()
key=sz.group('name') #命名组的获取
try:
htmlstr=re_charEntity.sub(CHAR_ENTITIES[key],htmlstr,1) #1表示替换第一个匹配
sz=re_charEntity.search(htmlstr)
except KeyError:
htmlstr=re_charEntity.sub('',htmlstr,1)
sz=re_charEntity.search(htmlstr)
return htmlstr

9.python爬虫--pyspider的更多相关文章

  1. Python爬虫-pyspider框架的使用

      pyspider 是一个用python实现的功能强大的网络爬虫系统,能在浏览器界面上进行脚本的编写,功能的调度和爬取结果的实时查看,后端使用常用的数据库进行爬取结果的存储,还能定时设置任务与任务优 ...

  2. [转]Python爬虫框架--pyspider初体验

    标签: python爬虫pyspider 2015-09-05 10:57 9752人阅读 评论(0) 收藏 举报  分类: Python(8)  版权声明:本文为博主原创文章,未经博主允许不得转载. ...

  3. Python爬虫进阶四之PySpider的用法

    审时度势 PySpider 是一个我个人认为非常方便并且功能强大的爬虫框架,支持多线程爬取.JS动态解析,提供了可操作界面.出错重试.定时爬取等等的功能,使用非常人性化. 本篇内容通过跟我做一个好玩的 ...

  4. python爬虫框架(2)--PySpider框架安装配置

    1.安装 1.phantomjs PhantomJS 是一个基于 WebKit 的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速.原生支持各种Web标准:DOM 处理 ...

  5. Python爬虫之PySpider框架

    概述 pyspider 是一个支持任务监控.项目管理.多种数据库,具有 WebUI 的爬虫框架,它采用 Python 语言编写,分布式架构.详细特性如下: 拥有 Web 脚本编辑界面,任务监控器,项目 ...

  6. [Python爬虫] 在Windows下安装PIP+Phantomjs+Selenium

    最近准备深入学习Python相关的爬虫知识了,如果说在使用Python爬取相对正规的网页使用"urllib2 + BeautifulSoup + 正则表达式"就能搞定的话:那么动态 ...

  7. python爬虫如何入门

    学爬虫是循序渐进的过程,作为零基础小白,大体上可分为三个阶段,第一阶段是入门,掌握必备的基础知识,第二阶段是模仿,跟着别人的爬虫代码学,弄懂每一行代码,第三阶段是自己动手,这个阶段你开始有自己的解题思 ...

  8. 芝麻软件: Python爬虫进阶之爬虫框架概述

    综述 爬虫入门之后,我们有两条路可以走. 一个是继续深入学习,以及关于设计模式的一些知识,强化Python相关知识,自己动手造轮子,继续为自己的爬虫增加分布式,多线程等功能扩展.另一条路便是学习一些优 ...

  9. Python爬虫开发与项目实战

    Python爬虫开发与项目实战(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1MFexF6S4No_FtC5U2GCKqQ 提取码:gtz1 复制这段内容后打开百度 ...

随机推荐

  1. 使用树莓派实现(山寨)高清视频叠加(HDMI OSD)

    项目需要在HDMI上叠加一些字符包括汉字和数值,要求不能使用台式机,本身也没有HDMI采集卡驱动开发能力,所以通过海思的HDMI编码器将HDMI编码为h.264网络视频流,然后通过树莓派解码显示,做字 ...

  2. POJ 3675 Telescope(简单多边形和圆的面积交)

    Description Updog is watching a plane object with a telescope. The field of vision in the telescope ...

  3. Notes of the scrum meeting(12.12)

    meeting time:19:30~20:30p.m.,December 12th,2013 meeting place:3号公寓一层 attendees: 顾育豪                  ...

  4. HashMap get()返回值问题

    问题描述:在进行mysql查询必要字段后,需要根据id进行es其它数据字段的查询拼接.使用HashMap以id为key 以查询过来的数据值为value. 代码如下: Map<String,Int ...

  5. 3dContactPointAnnotationTool开发日志(十三)

      为了使生成的项目能够显示报错信息我又勾选了下面这几个选项:   然后生成的项目运行时可以显示错误信息了,貌似是shader是空的.   之前的代码是这么写的,调用了Shader.Find(),貌似 ...

  6. 3dContactPointAnnotationTool开发日志(九)

      今天的任务是实现选中接触点功能并添加模型或接触点的属性改变功能,先从最简单的位置x,y,z改变入手,于是创建了一个面板(PanelStatus),添加了几个InputField来让用户输入数值改变 ...

  7. 【nginx】nginx:利用负载均衡原理实现代码的热部署和灰度发布

    事情起因很简单,代码的改动量很大.而且刚接手服务器,对原有的代码进行了一定程度的重构.虽然在测试服务器上做了较多的测试工作,但是直接将代码送入生产环境还是不放心,万一配置出问题服务直接崩溃怎么解?万一 ...

  8. [BZOJ4942] [NOI2017]整数

    题目背景 在人类智慧的山巅,有着一台字长为1048576位(此数字与解题无关)的超级计算机,著名理论计算机科 学家P博士正用它进行各种研究.不幸的是,这天台风切断了电力系统,超级计算机 无法工作,而 ...

  9. BZOJ2226 & SPOJ5971:LCMSum——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2226 题目大意:给定一个n,求lcm(1,n)+lcm(2,n)+……+lcm(n,n). ———— ...

  10. BZOJ2653:middle——题解

    http://www.lydsy.com/JudgeOnline/problem.php?id=2653 Description 一个长度为n的序列a,设其排过序之后为b,其中位数定义为b[n/2], ...