python增量爬虫pyspider
1.为了能够将爬取到的数据存入本地数据库,现在本地创建一个MySQL数据库example,然后
在数据库中建立一张表格test,示例如下:
DROP TABLE IF EXISTS `test`;
CREATE TABLE `douban_db` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`url` varchar(20) NOT NULL,
`direct` varchar(30),
`performer` date,
`type` varchar(30),
`district` varchar(20) NOT NULL,
`language` varchar(30),
`date` varchar(30),
`time` varchar(30),
`alias` varchar(20) NOT NULL,
`score` varchar(30),
`comments` varchar(300),
`scenario` varchar(300),
`IMDb` varchar(30),
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
2.如果使用开源框架pyspider来进行爬虫的话,默认情况下,会把爬取到的结果存放到result.db这个sqilite数据库中,但是为了方便操作,我们将结果存放到mysql中。接下
来要做的一个操作就是重写on_result方法,实例化调用我们自己实现的SQL方法,具体
实例如下:
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
# Created on 2015-03-20 09:46:20
# Project: fly_spider
import re
from pyspider.database.mysql.mysqldb import SQL
from pyspider.libs.base_handler import *
class Handler(BaseHandler):
headers= {
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding":"gzip, deflate, sdch",
"Accept-Language":"zh-CN,zh;q=0.8",
"Cache-Control":"max-age=0",
"Connection":"keep-alive",
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
}
crawl_config = {
"headers" : headers,
"timeout" : 100
}
@every(minutes=24 * 60)
def on_start(self):
self.crawl('http://movie.douban.com/tag/', callback=self.index_page)
@config(age=10 * 24 * 60 * 60)
def index_page(self, response):
for each in response.doc('a[href^="http"]').items():
if re.match("http://movie.douban.com/tag/\w+", each.attr.href, re.U):
self.crawl(each.attr.href, callback=self.list_page)
@config(age=10*24*60*60, priority=2)
def list_page(self, response):
for each in response.doc('html > body > div#wrapper > div#content > div.grid-16-8.clearfix > div.article > div > table tr.item > td > div.pl2 > a').items():
self.crawl(each.attr.href, priority=9, callback=self.detail_page)
@config(priority=3)
def detail_page(self, response):
return {
"url": response.url,
"title": response.doc('html > body > #wrapper > #content > h1 > span').text(),
"direct": ",".join(x.text() for x in response.doc('a[rel="v:directedBy"]').items()),
"performer": ",".join(x.text() for x in response.doc('a[rel="v:starring"]').items()),
"type": ",".join(x.text() for x in response.doc('span[property="v:genre"]').items()),
# "district": "".join(x.text() for x in response.doc('a[rel="v:starring"]').items()),
# "language": "".join(x.text() for x in response.doc('a[rel="v:starring"]').items()),
"date": ",".join(x.text() for x in response.doc('span[property="v:initialReleaseDate"]').items()),
"time": ",".join(x.text() for x in response.doc('span[property="v:runtime"]').items()),
# "alias": "".join(x.text() for x in response.doc('a[rel="v:starring"]').items()),
"score": response.doc('.rating_num').text(),
"comments": response.doc('html > body > div#wrapper > div#content > div.grid-16-8.clearfix > div.article > div#comments-section > div.mod-hd > h2 > i').text(),
"scenario": response.doc('html > body > div#wrapper > div#content > div.grid-16-8.clearfix > div.article > div.related-info > div#link-report.indent').text(),
"IMDb": "".join(x.text() for x in response.doc('span[href]').items()),
}
def on_result(self, result):
if not result or not result['title']:
return
sql = SQL()
sql.replace('douban_db',**result)
关于上面这段代码,有下面几点需要说明的:
a. 为了避免服务器判断出客户端在进行爬虫操作,从而禁止ip访问(具体表现为出现403禁止访问),我们需要在发出请求的时候加上一个http头,伪装成使用浏览器访问,具体用法如下:
headers= {
"Accept":"text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Accept-Encoding":"gzip, deflate, sdch",
"Accept-Language":"zh-CN,zh;q=0.8",
"Cache-Control":"max-age=0",
"Connection":"keep-alive",
"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.101 Safari/537.36"
}
crawl_config = {
"headers" : headers,
"timeout" : 100
}
b. @every(minutes=24 * 60)表示每天执行一次
@config(age=10 * 24 * 60 * 60)表示数据10天后就过期了
c. 接下来是一个比较重要的地方,重写on_result方法,相当于实现了一个多态,程序在最后返回时,会执行on_result方法,默认的情况下,on_result是将数据刷入sqlite中,但是如果我们需要将数据插入mysql中,就需要重写on_result方法,具体使用如下:
def on_result(self, result):
if not result or not result['title']:
return
sql = SQL()
sql.replace('test',**result)
注意这里的if not result or not result[‘title’]:这句判断很重要,不然的会会报错,提示result是未定义类型的。
3.在上面的额代码中,提到了实例化调用我们自己实现的SQL方法,并且引用了from pyspider.database.mysql.mysqldb import SQL这个库文件,那么就必须在这个目录下实现这个库,具体如下:
把下面内容文文放到pyspider/pyspider/database/mysql/目录下命名为mysqldb.py
from six import itervalues
import mysql.connector
from datetime import date, datetime, timedelta
class SQL:
username = 'root' #数据库用户名
password = 'root' #数据库密码
database = 'test' #数据库
host = '172.30.25.231' #数据库主机地址
connection = ''
connect = True
placeholder = '%s'
def __init__(self):
if self.connect:
SQL.connect(self)
def escape(self,string):
return '`%s`' % string
def connect(self):
config = {
'user':SQL.username,
'password':SQL.password,
'host':SQL.host
}
if SQL.database != None:
config['database'] = SQL.database
try:
cnx = mysql.connector.connect(**config)
SQL.connection = cnx
return True
except mysql.connector.Error as err:
if (err.errno == errorcode.ER_ACCESS_DENIED_ERROR):
print "The credentials you provided are not correct."
elif (err.errno == errorcode.ER_BAD_DB_ERROR):
print "The database you provided does not exist."
else:
print "Something went wrong: " , err
return False
def replace(self,tablename=None,**values):
if SQL.connection == '':
print "Please connect first"
return False
tablename = self.escape(tablename )
if values:
_keys = ", ".join(self.escape(k) for k in values)
_values = ", ".join([self.placeholder, ] * len(values))
sql_query = "REPLACE INTO %s (%s) VALUES (%s)" % (tablename, _keys, _values)
else:
sql_query = "REPLACE INTO %s DEFAULT VALUES" % tablename
cur = SQL.connection.cursor()
try:
if values:
cur.execute(sql_query, list(itervalues(values)))
else:
cur.execute(sql_query)
SQL.connection.commit()
return True
except mysql.connector.Error as err:
print ("An error occured: {}".format(err))
return False
学习文档:http://blog.binux.me/2015/01/pyspider-tutorial-level-1-html-and-css-selector/
测试环境:http://demo.pyspider.org/
python增量爬虫pyspider的更多相关文章
- python增量爬虫
import pymysql def insert_db(db_table, issue, time_str, num_code): host = '127.0.0.1' user = 'root' ...
- 第三百六十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)基本的索引和文档CRUD操作、增、删、改、查
第三百六十二节,Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)基本的索引和文档CRUD操作.增.删.改.查 elasticsearch(搜索引擎)基本的索引 ...
- 四十一 Python分布式爬虫打造搜索引擎Scrapy精讲—elasticsearch(搜索引擎)基本的索引和文档CRUD操作、增、删、改、查
elasticsearch(搜索引擎)基本的索引和文档CRUD操作 也就是基本的索引和文档.增.删.改.查.操作 注意:以下操作都是在kibana里操作的 elasticsearch(搜索引擎)都是基 ...
- 《实战Python网络爬虫》- 感想
端午节假期过了,之前一直在做出行准备,后面旅游完又休息了一下,最近才恢复状态. 端午假期最后一天收到一个快递,回去打开,发现是微信抽奖中的一本书,黄永祥的<实战Python网络爬虫>. 去 ...
- Python 网络爬虫干货总结
Python 网络爬虫干货总结 爬取 对于爬取来说,我们需要学会使用不同的方法来应对不同情景下的数据抓取任务. 爬取的目标绝大多数情况下要么是网页,要么是 App,所以这里就分为这两个大类别来进行了介 ...
- 最全数据分析资料汇总(含python、爬虫、数据库、大数据、tableau、统计学等)
一.Python基础 Python简明教程(Python3) Python3.7.4官方中文文档 Python标准库中文版 廖雪峰 Python 3 中文教程 Python 3.3 官方教程中文版 P ...
- 零基础如何快速学习好Python网络爬虫?
Python网络爬虫上手很快,能够尽早入门,可是想精通确实是需求些时间,需求达到爬虫工程师的级别更是需求煞费苦心了,接下来共享的学习道路是针对小白或许学习Python网络爬虫不久的同伴们. 学习网络爬 ...
- Python简单爬虫入门三
我们继续研究BeautifulSoup分类打印输出 Python简单爬虫入门一 Python简单爬虫入门二 前两部主要讲述我们如何用BeautifulSoup怎去抓取网页信息以及获取相应的图片标题等信 ...
- Ubuntu下配置python完成爬虫任务(笔记一)
Ubuntu下配置python完成爬虫任务(笔记一) 目标: 作为一个.NET汪,是时候去学习一下Linux下的操作了.为此选择了python来边学习Linux,边学python,熟能生巧嘛. 前期目 ...
随机推荐
- Ambari安装之Ambari安装前准备(CentOS6.5)(一)
优秀博客 <Ambari--大数据平台的搭建利器> Ambari安装前准备 (一)机器准备 192.168.80.144 ambari01 (部署Ambari-server和Mirro ...
- nyoj_253:LK的旅行(旋转卡壳入门)
题目链接 求平面最大点对. 找凸包 -> 根据凸包运用旋转卡壳算法求最大点对(套用kuang巨模板) 关于旋转卡壳算法 #include<bits/stdc++.h> using n ...
- Linux项目自动部署
场景:linux中自动部署项目在工作中经常遇到,快速高效的部署项目能够大幅提高工作效率.现在将项目部署的过程记录下来,以供参考,其中用到的知识点现在还有很多不很清楚,后面要好好琢磨琢磨! 1 项目部署 ...
- 设计模式的征途—16.访问者(Visitor)模式
在患者就医时,医生会根据病情开具处方单,很多医院都会存在以下这个流程:划价人员拿到处方单之后根据药品名称和数量计算总价,而药房工作人员根据药品名称和数量准备药品,如下图所示. 在软件开发中,有时候也需 ...
- 那些年,用C#调用过的外部Dll
经常有人找到我咨询以前在csdn资源里分享的dll调用.算算也写过N多接口程序.翻一翻试试写篇随笔. 明华IC读写器DLL 爱迪尔门锁接口DLL 通用OPOS指令打印之北洋pos打印机dll 明泰非接 ...
- RSA简介(一)——数论原理
RSA是最常用的非对称加密算法. 所谓非对称加密,就是说有两个密钥,一个密钥加密只可以用另外一个密钥解密,一般一个作为公钥,公开给所有人用来加密用,而另一个用来解密其他拥有公钥的加密结果,叫做私钥.另 ...
- python 排序sorted
num = [3,2,4,6,5] anum = sorted(num) dnum = sorted(num,reverse=True) print '升序:',anum # 升序: [2, 3, 4 ...
- hdu2108 Shape of HDU 极角排序判断多边形
Problem Description 话说上回讲到海东集团推选老总的事情,最终的结果是XHD以微弱优势当选,从此以后,"徐队"的称呼逐渐被"徐总"所取代,海东 ...
- JS实现extend函数
//写一个函数,该函数的名称是extend,有两个参数:destination,source 1.如果destination和source都是json对象,完成从source到destination的 ...
- 点击文字选中radio
<html><body><form action="" name="form1" method="post"& ...