爬虫实战:使用Scrapy框架爬取当当网商品信息。(信息存入本地数据库)
一.Xpath表达式基础
1.XPath与正则表达式简单对比。
(1)XPath表达式效率高一些。
(2)正则表达式功能强大一点。
(3)一般来说,优先选择XPath,但是XPath解决不了的问题用正则表达式解决。
2.常用的XPath表达式:
/ 逐层提取。
//标签名 提取所有名为的标签。
//标签名[@属性=属性值] 提取属性为的标签。(起限制作用)
@属性名 代表取某个属性。
text() 提取标签下面的文本。
3.实例:
提取网页的标题:/html/title/text()
提取所有div标签://div
提取div中
标签的内容: //div[@class=’tools’]
二.当当网商品信息爬取实战
(1)建立爬虫文件夹dangdang
在cmd窗口中打开指定路径目录,在其中输入scrapy startproject命令并新建名为dangdang的爬虫文件。

创建完之后如图所示:

(2)搭建基于基本框架结构的爬虫程序,请访问网站地址访问以获取目标域名的具体信息。
将scrapy命令行工具部署至该目录,并运行生成器脚本以完成数据抓取操作。

在spiders文件中就新建了一个爬虫文件,如图所示:

(3)在PyCham中导入dangdandg爬虫工程后,首先在items.py文件中创建三个容器:title(用于存储标题),link(用于存储链接),comment(用于存储评论数)。然后,在items.py中创建三个容器:title(用于存储标题),link(用于存储链接),comment(用于存储评论数)。
# -*- coding: utf-8 -*-
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class DangdangItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
# 创建三个容器
title = scrapy.Field() # 存储标题
link = scrapy.Field() # 存储link
comment = scrapy.Field() # 存储评论数
(4)在完成items.py的定义后,则需着手编写爬虫脚本dd.py。
分析网址如下:
第2页:http://category.dangdang.com/pg2-cid4008123.html
第3页:http://category.dangdang.com/pg3-cid4008123.html
其规律较为明显。
提取标题(Title:):
通过分析网页源码获取相关信息。


分析可知,仅仅靠<a title 并不能筛选出所有的商品标题信息,还必须要有一个限定条件,观察可知:name="itemlist-picture"可以作为限定条件。
故XPath表达式可以表示为:提取所有的a标签,并且通过name=“itemlist-picture” 定位,然后提取title中的内容:
//a[@name="itemlist-picture”]/@title
同理提取链接(link):
//a[@name="itemlist-picture”]/@href
取评论(comment):
//a[@name=“itemlist-review”]/text()
故dd.py编写如下,for循环是实现分页爬取,这里爬取前9页。
# -*- coding: utf-8 -*-
import scrapy
# 所有的导入都是从核心目录开始定位。
from dangdang.items import DangdangItem
from scrapy.http import Request
class DdSpider(scrapy.Spider):
name = 'dd'
allowed_domains = ['dangdang.com']
start_urls = ['http://category.dangdang.com/pg1-cid4008123.html']
def parse(self, response):
item = DangdangItem() # 实例化items一个对象。
# 取标题
item["title"] = response.xpath("//a[@name='itemlist-picture' ]/@title").extract() #提取信息。
# 提取链接
item["link"] = response.xpath('//a[@name="itemlist-picture" ]/@href').extract()
# 提取评论数量
item["comment"] = response.xpath('//a[@name="itemlist-review"]/text()').extract()
yield item # 将爬取的数据提交到pipelines中进行处理
# 进入for循环实现逐页爬取。
for i in range(2, 10): # 爬取2-9页所有的商品信息。
url = 'http://category.dangdang.com/pg'+str(i)+'-cid4008123.html'
# 用yield返回。Request()里面的参数有网址,回调函数,
yield Request(url, callback=self.parse)
为了不遵守机器人协议,在setting文件中进行配置,并将ROBOTSTXT_OBEY变量的值从True调整为False。

(5)打开cmd运行爬虫文件测试一下。

运行结果:

(6) 将获取的数据存储于数据表中:
其中需要用到pipelines.py文件以及MySQL数据库。由于pipelines默认处于关闭状态,请确保已启用该功能模块。我们应前往设置界面启用该功能模块。

链接Mysql数据库:打开cmd窗口键入:mysql -u root -p 输入密码。

建立 dangdang 数据库(或可调用已存在的数据库),在所使用的数据库中进行操作,并生成 goods 表以存储爬取的数据信息。


建立完成后,在pipelines.py文件中将数据库连接上;编写代码用于生成SQL语句,并将获取的数据存入指定的数据库表中;运行完成后请确保及时关闭数据库以释放资源;特别注意异常处理流程
# -*- coding: utf-8 -*-
import pymysql #导入pymysql模块。
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.html
class DangdangPipeline(object):
def process_item(self, item, spider):#用循环将商品遍历出来。
conn = pymysql.connect(host="127.0.0.1", user="root", passwd="123456", db="dangdang")
for i in range(0, len(item["title"])):
title = item["title"][i]
link = item["link"][i]
comment = item["comment"][i]
# print(title+":"+link+":"+comment)
sql = "insert into goods(title,link,comment) values ('"+title+"','"+link+"','"+comment+"');"
#print(sql)
try:
conn.query(sql) # 执行sql语句
conn.commit()
except Exception as e:
print(e)
conn.close()
return item
再继续打开cmd窗口执行爬虫文件

在Mysql中键入Select * from goods;语句查询是否写入成功。

爬取成功。
