一、Scrapy介绍
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。
所谓网络爬虫,就是一个在网上到处或定向抓取数据的程序,当然,这种说法不够专业,更专业的描述就是,抓取特定网站网页的HTML数据。抓取网页的一般方法是,定义一个入口页面,然后一般一个页面会有其他页面的URL,于是从当前页面获取到这些URL加入到爬虫的抓取队列中,然后进入到新页面后再递归的进行上述的操作,其实说来就跟深度遍历或广度遍历一样。
scrapy整体结构框架如下:
scrapy.cfg
myproject/
__init__.py
items.py
pipelines.py
settings.py
spiders/
__init__.py
spider1.py
spider2.py
...
二、爬取过程
1、创建工程tutorial
在终端命令行输入命令scrapy startproject tutorial(tutorial为工程的名字),就创建了一个scrapy的爬虫工程:
C:\Users\yanyan> scrapy startproject tutorial
2015-06-10 15:45:03 [scrapy] INFO: Scrapy 1.0.0rc2 started (bot: scrapybot)
2015-06-10 15:45:03 [scrapy] INFO: Optional features available: ssl, http11
2015-06-10 15:45:03 [scrapy] INFO: Overridden settings: {}
New Scrapy project 'tutorial' created in:
/mnt/hgfs/share/tutorial
You can start your first spider with:
cd tutorial
scrapy genspider example example.com
2、查看下工程的结构
[root@bogon share]# tree tutorial/
tutorial/
├── tutorial
│ ├── __init__.py
│ ├── items.py #用于定义抽取网页结构
│ ├── pipelines.py #将抽取的数据进行处理
│ ├── settings.py #爬虫配置文件
│ └── spiders
│ └── __init__.py
└── scrapy.cfg #项目配置文件
3、定义抽取tutorial的网页结构,修改items.py(需要抽取哪些字段,就在items.py中定义)
这里我们抽取如下内容:
user_name = Field() # 评论用户的名字
user_ID = Field() # 评论用户的ID
userProvince = Field() # 评论用户来自的地区
content = Field() # 评论内容
good_ID = Field() # 评论的商品ID
good_name = Field() # 评论的商品名字
date = Field() # 评论时间
replyCount = Field() # 回复数
score = Field() # 评分
status = Field() # 状态
title = Field()
userLevelId = Field()
userRegisterTime = Field() # 用户注册时间
productColor = Field() # 商品颜色
productSize = Field() # 商品大小
userLevelName = Field() # 银牌会员,钻石会员等
userClientShow = Field() # 来自什么 比如来自京东客户端
isMobile = Field() # 是否来自手机
days = Field() # 天数
commentTags = Field() # 标签
具体见 https://github.com/xiaoquantou/jd_spider/tree/master/jd_spider 里面的items.py里的commentItem(Item)类。
4、创建spider
这个爬虫文件要放在..\tutorial\tutorial\spiders 目录下。
京东商品评论的spider,具体见 https://github.com/xiaoquantou/jd_spider/tree/master/jd_spider/spiders 里面的jd_comment.py。
spider是用户编写用于从单个网站(或者一些网站)爬取数据的类。
其包含了一个用于下载的初始URL,如何跟进网页中的链接以及如何分析页面中的内容, 提取生成 item 的方法。
为了创建一个Spider,您必须继承 scrapy.Spider 类,且定义以下三个属性:
name: 用于区别Spider。 该名字必须是唯一的,您不可以为不同的Spider设定相同的名字。
start_urls: 包含了Spider在启动时进行爬取的url列表。 因此,第一个被获取到的页面将是其中之一。 后续的URL则从初始的URL获取到的数据中提取。
parse(): 是spider的一个方法。 被调用时,每个初始URL完成下载后生成的 Response 对象将会作为唯一的参数传递给该函数。 该方法负责解析返回的数据(response data),提取数据(生成item)以及生成需要进一步处理的URL的 Request 对象。
一个典型的spider文件结构如下:
import scrapy
class DmozSpider(scrapy.spider.Spider):
name = "dmoz" #唯一标识,启动spider时即指定该名称
allowed_domains = ["dmoz.org"]
start_urls = [
"http://www.dmoz.org/Computers/Programming/Languages/Python/Books/",
"http://www.dmoz.org/Computers/Programming/Languages/Python/Resources/"
]
def parse(self, response):
filename = response.url.split("/")[-2]
with open(filename, 'wb') as f:
f.write(response.body)
5、修改pipelines.py文件
pipelines.py文件用于处理爬取下来的数据,可以存储在数据库中,也可以存储在文档中,具体存储方式,用户可以在该文件中自定义。
下面的例子,是将爬取的商品评论存储成json格式:
# -*- coding: utf-8 -*-
from scrapy import signals
import json
import codecs
class JsonWithEncodingCnblogsPipeline(object):
def __init__(self):
self.file = codecs.open('tutorial.json', 'w', encoding='utf-8')
def process_item(self, item, spider):
line = json.dumps(dict(item), ensure_ascii=False) + "\n"
self.file.write(line)
return item
def spider_closed(self, spider):
self.file.close()
注意类名为JsonWithEncodingtutorialPipeline哦!settings.py中会用到
6、修改settings.py,添加以下两个配置项
ITEM_PIPELINES = {
'tutorial.pipelines.JsonWithEncodingCnblogsPipeline': 300,
}
LOG_LEVEL = 'INFO'
7、运行spider,启动爬虫
在终端命令行进入上面的爬虫工程目录下,然后输入命令scrapy crawl 爬虫名称(tutorial_spider.py中定义的name)
[root@bogon tutorial]# cd C:\Users\yanyan\tutorial
C:\Users\yanyan\tutorial> scrapy crawl comment
8、查看结果
爬取下来的数据保存在 ..\tutorial下面的tutorial.json((pipelines.py中定义的名称))文件中,用sublime text打开,就能看到json格式的数据
9、如果有需要可以将结果转成txt文本格式,可参考另外一篇文章python将json格式的数据转换成文本格式的数据或sql文件
源码可在此下载:https://github.com/jackgitgz/tutorialSpider
10、从结果中取出评论和评分两个字段的值,分别存储在txt和excel中,代码如下:
# -*- coding: utf-8 -*-
import json
# 读取json格式数据
data = []
with open('C:\Users\yanyan\\tutorial\\tutorial.json') as f:
for line in f:
data.append(json.loads(line))
f.close()
# 保存为txt格式的文件
# import codecs
# file_object = codecs.open('comment.txt', 'w' ,"utf-8")
# for item in data:
# str = "%s#_#%s\r\n" % (item['content'],item['score'])
# file_object.write(str)
# file_object.close()
# 保存为excel格式的文件
import xlwt
file = xlwt.Workbook() #注意这里的Workbook首字母是大写
table = file.add_sheet('sheet 1')
# table.write(行,列,value)
row = 0
for item in data:
table.write(row,0,item['content'])
table.write(row,1,item['score'])
row += 1
file.save('comment.xlsx') #保存文件
参考:http://www.jianshu.com/p/a8aad3bf4dc4
http://www.cnblogs.com/rwxwsblog/p/4567052.html
https://github.com/jackgitgz/CnblogsSpider/blob/master/json2txt.py
http://blog.csdn.net/xiaoquantouer/article/details/51840332
https://github.com/xiaoquantou/jd_spider