scrapy爬取数据并存入mysql数据库
前言:使用scrapy有如下几步:
创建项目,
写爬虫文件,
写item文件,
写解析方式,
写管道文件,
调整设置信息,
运行爬虫。
项目的创建
配置好scrapy框架之后,打开命令行,输入
`scrapy startproject <项目名称> [项目地址]`来创建项目,
项目地址是可选变量。
创建好项目之后,项目结构是这样的
爬虫需要在spiders/目录下创建,可以有多个爬虫,创建方式不唯一,可以使用IDE手动添加py文件,也可以使用命令行工具输入`genspider <爬虫名>的方式创建。
写爬虫文件:
import scrapy
from tutorial.items import TutorialItem
class QuotesSpider(scrapy.Spider):
name = "quotes"
start_urls = [
'http://quotes.toscrape.com/',
]
def parse(self, response):
for quote in response.css('div.quote'):
item = TutorialItem()
text = quote.css('span.text::text').get()
author = quote.css('small.author::text').get()
tags = ''.join(quote.css('div.tags a.tag::text').getall())
text = text[0:50] + '...'
item['author'] = author
item['text'] = text
item['tags'] = tags
yield item
next_page = response.css('ul.pager a::attr(href)')
for a in next_page:
yield response.follow(a,callback = self.parse)
# yield {
# 'text': quote.css('span.text::text').get(),
# 'author': quote.css('small.author::text').get(),
# 'tags': quote.css('div.tags a.tag::text').getall(),
# }
从start_urls里开始请求,name属性是每个爬虫类必须要有的,并且唯一,也就是每2个爬虫不能有同样的name属性。
写item文件:
import scrapy
class TutorialItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
#quotes表
author = scrapy.Field()
text = scrapy.Field()
tags = scrapy.Field()
item文件只需要声明几个字段即可,声明的字段取决于你想要爬取的信息,想爬什么信息,就声明什么字段。
写解析方式:
解析方式就是爬虫文件里的parse方法,在请求url返回response之后,会默认调用parse方法,即所谓的callback方法,parse方法里需要将获取到的response进行数据提取,可以使用css选择器或者XPath选择器,返回一个item对象或者一个字典对象,如果需要自动跳转爬信息,可以使用如下的方法,先获取到目的地的url,之后yield response.follow()方法可以向发送请求,回调方法是目的地对应的解析函数,不一定是self.parse。
写管道文件:
import pymysql
class TutorialPipeline:
quotesInsert = '''insert into quotes(content,author,tags)
values('{text}','{author}','{tags}')'''
authorInsert = '''insert into author(name,birthdate,bio)
values('{name}','{birthdate}','{bio}')'''
def open_spider(self, spider):
self.conn = pymysql.connect('localhost', '<username>', '<passwd>', '<databasename>')
self.cursor = self.conn.cursor()
def process_item(self, item, spider):
if spider.name == 'author':
sqltext = self.authorInsert.format(
name=pymysql.escape_string(item['name']),
birthdate=pymysql.escape_string(item['birthdate']),
bio=pymysql.escape_string(item['bio']))
self.cursor.execute(sqltext)
elif spider.name == 'quotes':
sqltext = self.quotesInsert.format(
text=pymysql.escape_string(item['text']),
author=pymysql.escape_string(item['author']),
tags=pymysql.escape_string(item['tags']))
self.cursor.execute(sqltext)
self.conn.commit()
return item
def close_spider(self, spider):
self.cursor.close()
self.conn.close()
管道文件是当你的yield item或者字典对象之后,就会调用的方法,open_spider是运行爬虫的时候就会执行的方法,close_spider是爬虫爬完数据会执行的方法,process_item是从爬虫文件中yield对象到管道之中才会执行的方法。
调整设置信息:
在settings.py文件里面找到
ITEM_PIPELINES = {
'tutorial.pipelines.TutorialPipeline': 300,
}
并把它打开,目的是打开管道,不然yield的对象不会到管道里面去执行。
运行爬虫:
打开命令行工具,进入项目,输入scrapy crawl <spider_name>
即可运行爬虫,会输出许多日志信息。