【问题标题】:Scrapy Pipeline to update mysql for each start_urlScrapy Pipeline 为每个 start_url 更新 mysql
【发布时间】:2017-04-13 03:34:31
【问题描述】:

我有一个蜘蛛,它从 MySQL 数据库中读取 start_urls 并从每个页面中抓取未知数量的链接。我想使用 pipelines.py 使用抓取的链接更新数据库,但我不知道如何将 start_url 重新放入 SQL UPDATE 语句的管道中。

这是有效的蜘蛛代码。

import scrapy
import MySQLdb
import MySQLdb.cursors
from scrapy.http.request import Request

from youtubephase2.items import Youtubephase2Item

class youtubephase2(scrapy.Spider):
name = 'youtubephase2'

def start_requests(self):
    conn = MySQLdb.connect(user='uname', passwd='password', db='YouTubeScrape', host='localhost', charset="utf8", use_unicode=True)
    cursor = conn.cursor()
    cursor.execute('SELECT resultURL FROM SearchResults;')
    rows = cursor.fetchall()

    for row in rows:
        if row:
            yield Request(row[0], self.parse)
    cursor.close()

def parse(self, response):
    for sel in response.xpath('//a[contains(@class, "yt-uix-servicelink")]'):
        item = Youtubephase2Item()
        item['pageurl'] = sel.xpath('@href').extract()
        yield item

这里是 pipeline.py,我想用 start_url 作为 SQL UPDATE 语句的 WHERE 条件抓取的链接来更新数据库。所以 SQL 语句中的 start_url 是我想要完成的占位符。

import MySQLdb
import MySQLdb.cursors
import hashlib
import re
from scrapy import log
from scrapy.exceptions import DropItem
from twisted.enterprise import adbapi
from youtubephase2.items import Youtubephase2Item

class MySQLStorePipeline(object):
    def __init__(self):
        self.conn = MySQLdb.connect(user='uname', passwd='password', db='YouTubeScrape', host='localhost', charset="utf8", use_unicode=true)
        self.cursor = self.conn.cursor()

def process_item(self, item, spider):
    try:

        self.cursor.execute("""UPDATE SearchResults SET PageURL = %s WHERE ResultURL = start_url[
                    VALUES (%s)""",
                   (item['pageurl']
                                    ))

        self.conn.commit()

    except MySQLdb.Error, e:
        log.msg("Error %d: %s" % (e.args[0], e.args[1]))

    return item

希望我的问题足够清楚。我过去曾成功使用 pipeline.py 将项目插入数据库。

【问题讨论】:

    标签: python scrapy scrapy-pipeline


    【解决方案1】:

    您可以使用metaRequest参数在相关请求和项目之间传递相关信息:

    def start_requests(self):
        conn = MySQLdb.connect(user='uname', passwd='password', db='YouTubeScrape', host='localhost', charset="utf8", use_unicode=True)
        cursor = conn.cursor()
        cursor.execute('SELECT resultURL FROM SearchResults;')
        rows = cursor.fetchall()
    
        for row in rows:
            if row:
                yield Request(row[0], self.parse, meta=dict(start_url=row[0]))
        cursor.close()
    
    def parse(self, response):
        for sel in response.xpath('//a[contains(@class, "yt-uix-servicelink")]'):
            item = Youtubephase2Item()
            item['pageurl'] = sel.xpath('@href').extract()
            item['start_url'] = response.meta['start_url']
            yield item
    

    现在,您也可以使用 response.url,但这可能会因为重定向或其他原因而改变,因此以后可能会与您数据库中的内容有所不同。

    最后,您必须更新您的管道以将item['start_url'] 作为start_url 参数传递给您的cursor.execute

    【讨论】:

    • 非常感谢您的快速回复。效果很好!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-25
    • 2015-02-15
    • 1970-01-01
    • 1970-01-01
    • 2014-02-27
    • 1970-01-01
    相关资源
    最近更新 更多