假设有这样一个需求,我们准备爬取如上图所示,京东商城的手机销售列表的信息,并存入到数据库中。 从图中,我们可以看到,准备存储这几个字段
图片(imageUrl)
,价格(price)
,产品描述(description)
,评论数(commentNum)
,店名(shopName)
并且,我们还需要考虑分页爬取的问题。这里我们使用mysql数据库进行存储。Mysql操作这边我会说的很简单,毕竟不是我们本篇文章的重点。首先我们先创建数据库和存储的表。如下
CREATE DATABASE phonedb;
create table good(
id INT NOT NULL AUTO_INCREMENT,
imageUrl VARCHAR(255) COMMENT ‘图片’,
price DOUBLE DEFAULT 0 COMMENT ‘价格’,
description VARCHAR(255) COMMENT ‘产品描述’,
commentNum INT DEFAULT 0 COMMENT ‘评论数’,
shopName VARCHAR(50) COMMENT ‘店名’,
PRIMARY KEY ( id ) );
创建完的表如下图
以上mysql数据库都弄完成了,接下来就开始讲怎么用scrapy框架将数据存储到msyql的数据库中。 关于怎么创建scrapy在之前的章节已经讲过了,可以看看之前的文章。
- 首先我们创建一个叫phonepro的scrapy项目
scrapy startproject phonepro
- 进入phonepro项目目录
cd phonepro
- 创建一个名为jdPhoneSpider 的basic爬虫
scrapy genspider -t basic jdPhoneSpider search.jd.com
- 创建完项目,我这边用PyCharm软件打开项目,项目结构如下
- 修改item.py,定义数据体
class PhoneproItem(scrapy.Item):
# define the fields for your item here like:
imageUrl = scrapy.Field()
price = scrapy.Field()
description = scrapy.Field()
commentNum = scrapy.Field()
shopName = scrapy.Field()
- 编写spider爬虫文件
class JdphonespiderSpider(scrapy.Spider):
name = ‘jdPhoneSpider’
allowed_domains = [‘search.jd.com’]
start_urls = [‘http://search.jd.com/‘]
def start_requests(self):
for i in range(1, 100):
url = ‘https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&cid2=653&cid3=655&s=1&click=0&page=‘ + str( 2 i - 1)
yield self.make_requests_from_url(url)
def parse(self, response):
item = PhoneproItem()
images = response.xpath(‘//[@id=”J_goodsList”]/ul/li/div/div[1]/a/img/@source-data-lazy-img’).extract()
prices = response.xpath(‘//[@id=”J_goodsList”]/ul/li/div/div[3]/strong/i/text()’).extract()
descriptions = response.xpath(‘//[@id=”J_goodsList”]/ul/li/div/div[4]/a/@title’).extract()
shopNames = response.xpath(‘//[@id=”J_goodsList”]/ul/li/div/div[7]/span/a/@title’).extract()
for i,j,k,l in zip(images,prices,descriptions,shopNames):
item[“imageUrl”] = “https:”+i
item[“price”] = j
item[“description”] = k
item[“shopName”] = l
yield item
这里我们重写了start_requests的方法,主要是为了方便对分页网址进行处理。 有两个点需要注意一下,事实上每页有60条数据,不过这里会发现过滤出来的只有30条,因为一些网站本身内部加载的问题,我们这边只是对网页数据进行过滤,正常爬取的话都是直接爬出获取数据的ajax在进行爬取的,我这边主要是为了顺便展示一些如何通过xpath过滤出自己想要的网页数据。所以这些可以不用在意。另外价格在网页中是过滤不到的,这边我们也暂时忽略,因为这不是本篇文章的重点。
- 接下来开始编写通道,就是我们这章的重点,在通道中将数据存入mysql数据库。 先在settings文件中设置一下通道,如下
# Configure item pipelines # See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
‘phonepro.pipelines.PhoneproPipeline’: 300,
}
因为我们需要操作mysql数据库,这边我们需要安装mysql-connector 很简单,直接用
pip install mysql-connector
既可以实现安装。之后,编写PhoneproPipeline类:
import mysql.connector
class PhoneproPipeline(object):
def open_spider(self, spider):
# 创建数据库连接
self.mydb = mysql.connector.connect(
host=“localhost”, #地址
user=“root”, #用户名
passwd=“*“,#密码
database=“phonedb” #数据库名称
)
self.cu = self.mydb.cursor()
def process_item(self, item, spider):
print(spider.name, “PhoneproPipeline”)
# 插入语句
insert_sql = “insert into good (imageUrl,price,description,shopName) VALUES (%s,%s,%s,%s)”
nsert_value = (item[“imageUrl”], float(item[“price”]),item[“description”],item[“shopName”])
print(insert_sql)
self.cu.execute(insert_sql,insert_value)
self.mydb.commit()
return item
def spider_close(self, spider):
# 关闭数据库
self.mydb.close()
代码很简单,这边就不讲了。然后通过
scrapy crawl jdPhoneSpider –nolog
执行爬虫 这个时候爬取的数据就存入数据库了。 如下图
欢迎关注本人公众号和小程序,谢谢