python爬虫框架scrapy学习第一课
windows10 scrapy的安装
1.先安装python。测试python是否安装成功或查询安装的版本,在命令行下输入: python --version
2.最初采用网上介绍的一步到位安装方式,在命令行直接输入如下命令:
pip install scrapy
执行过程报错,建议升级pip。按照要求执行如下命令:
python -m pip install --upgrade pip
上述命令执行成功后,继续执行pip install scrapy仍然报错,百度后发现需要分步骤进行。
3. 先在命令行下执行如下命令:
pip install wheel
pip install pyOpenSSL
安装成功,继续执行
pip install twisted
这里报错,问题是缺少对应的安装文件,下载对应python版本的和操作系统的twisted安装包。电脑64位,python3.7.0,选择安装包版本为:Twisted-18.9.0-cp37-cp37m-win_amd64.whl。在该文件的存放路径下,执行
pip install Twisted-18.9.0-cp37-cp37m-win_amd64.whl
安装成功后,再执行pip install scrapy命令,scrapy即可安装成功。在命令行输入如下命令,出现版本号,即表示安装成功。
scrapy --version
第一个scrapy爬虫应用
根据scrapy的中文指导手册,建立第一个scrapy实例。由于对文档理解不深入,踩了诸多坑,记录如下。
创建项目
选定一个存储代码的目录,执行如下命令。路径中会存在一个tutorial文件夹
scrapy startproject tutorial
tutorial文件层次及含义如下:
在tutorial/spiders路径下执行如下命令,创建一个名为itcast的爬虫,并指定爬取域的范围。
scrapy genspider itcast “itcast.cn”
在文件tutorial\spiders路径中生成一个itcast.py文件。添加如下代码
import scrapy
class ItcastSpider(scrapy.Spider):
name = 'itcast'
allowed_domains = ['itcast.com']
start_urls = ("http://www.itcast.cn/channel/teacher.shtml",)
def parse(self, response):
filename = "teacher.html"
with open(filename, 'wb') as f:
f.write(response.body)
要建立一个Spider, 你必须用scrapy.Spider类创建一个子类,并确定了三个强制的属性 和 一个方法。
1.name = “” :这个爬虫的识别名称,必须是唯一的,在不同的爬虫必须定义不同的名字。
2.allow_domains = [] 是搜索的域名范围,也就是爬虫的约束区域,规定爬虫只爬取这个域名下的网页,不存在的URL会被忽略。
3.start_urls = () :爬取的URL元祖/列表。爬虫从这里开始抓取数据,所以,第一次下载的数据将会从这些urls开始。其他子URL将会从这些起始URL中继承性生成。
4.parse(self, response) :解析的方法,每个初始URL完成下载后将被调用,调用的时候传入从每一个URL传回的Response对象来作为唯一参数,主要作用如下:负责解析返回的网页数据(response.body),提取结构化数据(生成item)生成需要下一页的URL请求。
代码中将爬取到的数据存储在teacher.html中,在tutorial目录下执行如下命令:
scrapy crawl itcast
发现报 No module named win32api错误,windows系统上出现这个问题的解决办法是安装Py32Win模块,执行如下命令即可安装成功
pip install pypiwin32
再次执行scrapy crawl itcast,发现数据爬取正常,生成一个html文件,里面存放了网页端静态页面信息
取数据
由于爬取的是整个页面的数据,为了获取有效信息,需要对获取的数据进行筛选,选择我们感兴趣的数据源。因此要定义提取数据的item。
定义item
修改原始item.py文件
import scrapy
# class TutorialItem(scrapy.Item):
# # define the fields for your item here like:
# # name = scrapy.Field()
# pass
class ItcastItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
name = scrapy.Field()
title = scrapy.Field()
info = scrapy.Field()
在itcast.py文件中使用ItcastItem类
# -*- coding: utf-8 -*-
import scrapy
from tutorial.items import ItcastItem
class ItcastSpider(scrapy.Spider):
name = 'itcast'
allowed_domains = ['itcast.com']
start_urls = ("http://www.itcast.cn/channel/teacher.shtml",)
def parse(self, response):
items = []
for each in response.xpath("//div[@class='li_txt']"):
item = ItcastItem()
name = each.xpath("h3/text()").extract()
title = each.xpath("h4/text()").extract()
info = each.xpath("p/text()").extract()
item['name'] = name[0]
item['title'] = title[0]
item['info'] = info[0]
items.append(item)
return items
这里用到xpath功能:
xpath(): 传入xpath表达式,返回该表达式所对应的所有节点的selector list列表
extract(): 序列化该节点为unicode字符串并返回list。
//div[@class=‘li_txt’]:表示获取的数据中所有div模块下class等于li_txt的内容。
数据保存为json文件
命令行执行:
scrapy crawl itcast -o teachers.json
生成json数据,保存的不是中文而是unicode字符,网上推荐的有2种方式。
方式一:修改pipeline.py文件
class JsonWithEncodingPipeline(object):
def __init__(self):
self.file = codecs.open('scraped_data_utf8.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()
结论:本地测试没有成功,不确定是否是操作有误导致?
方式二:修改settings.py,在文件中增加一行
FEED_EXPORT_ENCODING = 'utf-8'
结论:测试通过,json文件变为中文。
数据保存为csv文件
命令行执行:
scrapy crawl itcast -o teachers.csv
生成csv文件,双击直接打开,乱码。用nodepad++打开,显示正常。测试网上3种解决办法,只有一种可以成功。
方式一:修改settings.py,在文件中增加一行
FEED_EXPORT_ENCODING = 'gbk'
结论:本地测试没有通过。
方式二:用nodepad++打开,修改文件格式为utf-8,保存后再双击打开。
结论:本地测试没有通过
方式三:用记事本打开,保存文件时,选择utf-8模式,再次双击打开文件。
结论:本次测试通过,csv文件中文显示正常