本章将从案例开始介绍 python scrapy 框架,更多内容请参考: python 学习指南
- scrapy startproject cnblogSpider
scrapy.cfg: 项目部署文件
cnblogSpider/: 该项目的 python 模块,之后可以在此加入代码
cnblogSpider/items.py: 项目中的 item 文件。
cnblogSpider/pipelines.py: 项目中的 Pipelines 文件。
cnblogSpider/settings.py: 项目的配置文件。
cnblogSpider/spiders/: 放置 Spider 代码的目录。
我们打算抓取:" http://www.cnblogs.com/miqi1992/default.html?page=2 " 网站里博客地址、标题、创建时间、文本。
class CnblogspiderItem(scrapy.Item):
# define the fields for your item here like:
url = scrapy.Field()
time = scrapy.Field()
title = scrapy.Field()
content = scrapy.Field()
```
爬虫功能主要分两步:
目录下创建一个名为 cnblog 的爬虫,并制定爬取域的范围:
- cnblogSpider/spiders
- scrapy genspider cnblog "cnblogs.com"
目录下的 cnblog,默认增加了下列代码: ```python
- cnblogSpider/spiders
class CnblogSpider(scrapy.Spider):
name = 'cnblog'
allowed_domains = ['cnblogs.com']
start_urls = [' http://cnblogs.com/ ']
- def parse(self, response):
- pass
```
其实也可以由我们自行创建 cnblog.py 并编写上面的代码,只不过使用命令可以免去编写固定代码的麻烦
要建立一个 Spider, 你必须用 scrapy.Spider 类创建一个子类,并确定了三个强制的属性和一个方法。
: 解析的方法,每个初始 URL 完成下载后将被调用,调用的时候传入从每一个 URL 传回的 Response 对象来作为唯一参数,主要作用如下:
- parse(self, response)
将 start_urls 的值改为需要爬取的第一个 url:
- start_urls = ("http://www.cnblogs.com/miqi1992/default.html?page=2")
修改 parse() 方法
- def parse(self, response):
- filename = "cnblog.html"
- with open(filename, 'w') as f:
- f.write(response.body)
然后运行一下看看,在 cnblogSpider 目录下运行:
- scrapy crawl cnblog
是的,就是 cnblog, 看上面代码,它是 CnblogSpider 类的 name 属性,也就是 scrapy genspider 命令的唯一爬虫名。
运行之后,如果打印的日志出现
,代表执行完成。之后当前文件夹中就出现了一个 cnblog.html 文件,里面就是我们刚刚要爬取的网页的全部源代码信息。
- [scrapy]INFO: Spider closed(finished)
- #注意,Python2.x默认编码环境是ASCII,当和取回的数据编码格式不一致时,可能会造成乱码;
- #我们可以指定保存内容的编码格式,一般情况下,我们可以在代码最上方添加:
- import os
- reload(sys)
- sys.setdefaultencoding('utf-8')
- #这三行代码是Python2.x里面解决中文编码的万能钥匙,警告这么多年的吐槽后Python3学乖了,默认编码是Unicode了
- <div class="day">
- <div class="dayTitle">...</div>
- <div class="postTitle">...</div>
- <div class="postCon">...</div>
- </div>
是不是一目了然?直接上 XPath 开始提取数据吧。
- from cnblogSpider.items import CnblogspiderItem
form cnblogSpider.items import CnblogspiderItem
def parse(self, response):
# print(response.body)
# filename = "cnblog.html"
# with open(filename,'w') as f:
# f.write(response.body)
- #存放博客的集合
- items = []
- for each in response.xpath(".//*[@class='day']"):
- item = CnblogspiderItem()
- url = each.xpath('.//*[@class="postTitle"]/a/@href').extract()[0]
- title = each.xpath('.//*[@class="postTitle"]/a/text()').extract()[0]
- time = each.xpath('.//*[@class="dayTitle"]/a/text()').extract()[0]
- content = each.xpath('.//*[@class="postCon"]/div/text()').extract()[0]
- item['url'] = url
- item['title'] = title
- item['time'] = time
- item['content'] = content
- items.append(item)
- #直接返回最后数据
- return items
```
scrapy 保存信息的最简单的方法主要有四种, -o 输出指定格式的文件,命令如下:
- #json格式,默认为Unicode编码
- scrapy crawl cnblog -o cnblog.json
- #json lines格式,默认为Unicode编码
- scrapy crawl cnblog -o cnblog.jsonl
- #csv逗号表达式,可用excel打开
- scrapy crawl cnblog -o cnblog.csv
- #xml格式
- scrapy crawl cnblog -o cnblog.xml
- form cnblogSpider.items import CnblogspiderItem
- def parse(self, response):
- # print(response.body)
- # filename = "cnblog.html"
- # with open(filename, 'w') as f:
- # f.write(response.body)
- #存放博客的集合
- # items = []
- for each in response.xpath(".//*[@class='day']"):
- item = CnblogspiderItem()
- url = each.xpath('.//*[@class="postTitle"]/a/@href').extract()[0]
- title = each.xpath('.//*[@class="postTitle"]/a/text()').extract()[0]
- time = each.xpath('.//*[@class="dayTitle"]/a/text()').extract()[0]
- content = each.xpath('.//*[@class="postCon"]/div/text()').extract()[0]
- item['url'] = url
- item['title'] = title
- item['time'] = time
- item['content'] = content
- # items.append(item)
- #将获取到的数据交给pipelines
- yield item
- #直接返回最后数据,不经过pipelines
- #return items
来源: https://www.cnblogs.com/miqi1992/p/8120215.html