简书爬虫代码(用selenium获取通过ajax加载的数据)

在某些爬虫项目下,我们需要每次执行一条插入语句,就立即调用commit方法更新数据库,如果爬取时间太长,中途可能被迫中断,这样程序就不能执行close_spider中的commit。但如果在insert_db中直接加入commit,又会使程序执行变得很慢。这里就可以使用Twisted中提供的以异步方式多线程访问数据库的模块adbapi,可以显著提供程序访问数据库的效率。

adbapi.ConnectionPool

方法可以创建一个数据库连接池对象,其中包括多个连接对象,每个连接对象在独立的线程中工作。adbapi只是提供了异步访问数据库的编程框架,再其内部依然使MySQLdb这样的库访问数据库。

dbpool.runInteraction(insert_db,item)

以异步方式调用insert_db函数,dbpool会选择连接池中的一个连接对象在独立线程中调用insert_db,其中参数item会被传给insert_db的第二个参数,传给insert_db的第一个参数是一个Transaction对象,其借口与Cursor对象类似,可以调用execute方法执行SQL语句,insert_db执行后,连接对象会自动调用commit方法。

settings.py配置

js.py

from scrapy.linkextractorsimport LinkExtractor

from scrapy.spidersimport CrawlSpider, Rule

from jianshu.itemsimport JianshuItem

class JsSpider(CrawlSpider):

    name= 'js'

    allowed_domains= ['jianshu.com']

    start_urls= ['http://jianshu.com/']

    rules= (Rule(LinkExtractor(allow=r'.*/p/[0-9a-z]{12}.*'),callback='parse_item',follow=True),)

    def parse_item(self,response):

        title= response.xpath("//h1[@class='_1RuRku']/text()").get()

        content= response.xpath("//article[@class='_2rhmJa']").get()

        avatar= response.xpath("//img[@class='_13D2Eh']/@src").get()

        author= response.xpath("//a[@class='_1OhGeD']/text()").get()

        pub_time= response.xpath("//div[@class='s-dsoj']/time/text()").get()

        url= response.url

        author_id= url.split('/')[-1]

        item=JianshuItem(title=title,content=content,avatar=avatar,author=author,pub_time=pub_time,author_id=author_id,origin_url=url)

        return item

items.py

import scrapy

class JianshuItem(scrapy.Item):

    title= scrapy.Field()

    author= scrapy.Field()

    avatar= scrapy.Field()

    pub_time= scrapy.Field()

    author_id= scrapy.Field()

    content= scrapy.Field()

    origin_url= scrapy.Field()

middlewares.py(selenium中间件

from seleniumimport webdriver

import time

from scrapy.http.response.htmlimport HtmlResponse

class SeleniumDownloadMiddleware(object):

    def __init__(self):                self.driver=webdriver.Chrome(executable_path=r'E:\Python_practice\Software\chromedriver_win32\chromedriver.exe')

    # 下载器中间件

    def process_request(self,request,spider):

        self.driver.get(request.url)

        time.sleep(1)

        soure= self.driver.page_source

        response= HtmlResponse(url=self.driver.current_url,body=soure,request=request,encoding='utf-8')

        return response

pipelines.py

import pymysql

class JianshuPipeline(object):

    def __init__(self):

        dbparams={

            'host': '127.0.0.1',

            'port': 3307,

            'user': 'xmy',

            'password': 'gyf001004',

            'database': 'jianshu',

            'charset': 'utf8',

    }

        self.coon= pymysql.Connect(**dbparams)

        self.cursor= self.coon.cursor()

        self._sql= None

    def process_item(self,item,spider):

        self.cursor.execute(self.sql,(item['title'],item['author'],item['avatar'],item['pub_time'],item['author_id'],item['origin_url'],item['content']))

        self.coon.commit()

        return item

    @property

    def sql(self):

        if not self._sql:

            self._sql= """

            insert into article(id,title,author,avatar,pub_time,author_id,origin_url,content) values(null,%s,%s,%s,%s,%s,%s,%s)

"""

            return self._sql

    return self._sql

通过twisted.enterprise.adbapi异步下载

import pymysql

from twisted.enterprise import adbapi

from pymysqlimport cursors

class JianshuTwistedPipeline(object):

    def __init__(self):

        dbparams= {

            'host': '127.0.0.1',

            'port': 3307,

            'user': 'xmy',

            'password': 'gyf001004',

            'database': 'jianshu',

            'charset': 'utf8',

            'cursorclass': cursors.DictCursor

    }

        self.dbpool= adbapi.ConnectionPool('pymysql',**dbparams)

        self._sql= None

    @property

    def sql(self):

        if not self._sql:

            self._sql= """

                insert into article(id,title,author,avatar,pub_time,author_id,origin_url,content) values(null,%s,%s,%s,%s,%s,%s,%s)

"""

            return self._sql

    return self._sql

    def process_item(self,item,spider):

        defer= self.dbpool.runInteraction(self.insert_item,item)

        defer.addErrback(self.handle_error,item,spider)

    def insert_item(self,cursor,item):

        cursor.execute(self.sql,(item['title'],item['author'],item['avatar'],item['pub_time'],item['author_id'],item['origin_url'],item['content']))

    def handle_error(self,error,item,spider):

        print('='*10+"error"+'='*10)

        print(error)

        print('='*10+"error"+'='*10)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,098评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,213评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,960评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,519评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,512评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,533评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,914评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,574评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,804评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,563评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,644评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,350评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,933评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,908评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,146评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,847评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,361评论 2 342

推荐阅读更多精彩内容