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/

### 回答1: 好的。 如果要使用 PySpider一个爬虫,首先需要安装 PySpider。你可以使用 pip 安装: ``` pip install pyspider ``` 然后就可以开始编写爬虫了。 爬虫一般分为四个部分: 1. **爬取策略**:确定爬取的目标网站、爬取的数据以及爬取的顺序。 2. **网络请求**:使用 Python 的网络库(如 requests、urllib 等)向目标网站发送网络请求,获取网页内容。 3. **HTML 解析**:使用 Python 的 HTML 解析库(如 Beautiful Soup、pyquery 等)解析网页内容,提取出想要的数据。 4. **数据存储**:将提取出的数据存储到文件、数据库或其他存储介质中。 下面是一个使用 PySpider 写的简单爬虫的示例: ```python import pyspider # 定义爬虫类 class Spider(pyspider.Spider): # 定义爬虫的名称和爬取的目标网站 name = 'my_spider' start_urls = ['http://www.example.com/'] # 定义爬虫的爬取策略 def on_start(self): self.crawl(self.start_urls[0], callback=self.index_page) # 定义爬虫的回调函数,处理爬取到的数据 def index_page(self, response): # 使用 Beautiful Soup 解析网页内容 soup = BeautifulSoup(response.text, 'html.parser') # 提取需要 ### 回答2: 使用Pyspider编写一个爬虫非常简单。在使用之前,我们需要确保已经安装Python和Pyspider,可以使用pip命令进行安装。 首先,我们需要导入必要的模块和类。在Pyspider中,我们需要使用三个类:CrawlSpider类,BaseHandler类和PhantomJSHandler类。 ``` from pyspider.libs.base_handler import * from pyspider.libs.phantomjs_handler import * ``` 接下来,我们需要创建一个Handler类,该类将继承BaseHandler类。在这个类中,我们可以定义我们要爬取的网站和解析器。例如,我们可以定义一个`on_start`方法来指定初始URL。 ``` class MySpiderHandler(BaseHandler): crawl_config = { 'headers': { 'User-Agent':'Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)' } } def on_start(self): self.crawl('http://www.example.com', callback=self.index_page) def index_page(self, response): # 解析网页并提取所需信息 pass ``` 然后,我们需要实例化这个爬虫类,并使用`phantomjs`参数指定使用PhantomJS作为浏览器引擎。 ``` if __name__ == '__main__': configure_logging() phantomjs_handler = PhantomJSHandler() phantomjs_handler.on_start() ``` 最后,可以在命令行中运行脚本来启动爬虫。 ``` $ python spider.py ``` 这就是使用Pyspider编写爬虫的基本步骤。当然,根据实际需求,我们还可以添加更多的功能和功能扩展。 ### 回答3: Pyspider一个基于Python开发的强大的爬虫框架,可以帮助我们方便地爬取网页数据。下面是一个简单示例,用300字中文回答如何用Pyspider写个爬虫: 首先,我们需要安装Pyspider。在命令行中使用pip install pyspider进行安装。 接下来,我们创建一个名为spider的Python文件。在文件中,我们首先导入必要的库,比如from pyspider.libs.base_handler import * 然后,我们创建一个名为MySpider的类,继承BaseHandler。在这个类中,我们需要定义一些必要的属性和方法。 1. start_urls: 爬虫的起始链接,可以是一个列表或者字符串。 2. crawl_config: 爬虫的配置,比如深度、并发数量等。 在类中,我们需要定义一个on_start方法,用于指定爬虫启动时要执行的操作。比如可以使用self.crawl方法从起始链接开始爬取数据。 我们还需要定义一个on_response方法,用于处理每个请求的响应。在这个方法中,我们可以使用response.doc(如果需要解析HTML)或response.text(如果是JSON数据)来获取返回的内容,并对其进行解析和处理。 此外,我们还可以在类中定义其他辅助方法,比如解析HTML或JSON数据的方法,保存数据的方法等。 最后,我们需要在文件的最后添加一行代码,如下所示: if __name__ == '__main__': MySpider().run() 这样,我们的爬虫就可以通过运行python spider.py命令来启动了。 以上是一个简单的Pyspider爬虫示例,当然在实际应用中可能还需要更复杂的逻辑和处理。通过学习Pyspider的文档和示例,我们可以进一步掌握如何使用Pyspider来开发更强大的爬虫
评论 12
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值