本文参考借鉴scrapy官方教程和小甲鱼python教程
之前安装好了scrapy,现在开始试着进行一个小任务:
爬取dmoz上的一个网页:
'http://www.dmoztools.net/Computers/Programming/Languages/Python/Books/' 'http://www.dmoztools.net/Computers/Programming/Languages/Python/Resources/
Scarpy爬取网站的四个步骤:
1 创建Scarpy项目
2 定义Item容器
3 编写爬虫
4 存储内容

第一步:创建创建Scarpy项目
在cmd中输入:
scrapy startproject SpiderNO1

此时桌面生成一个文件夹

其中scrapy.cfg为项目配置文件,默认保存即可;
(1)子文件夹SpiderNO1中存放着模块的代码
(2)SpiderNO1 /: 项目python模块, 之后您将在此加入代码
(3)SpiderNO1 /items.py: 项目items文件
(4)SpiderNO1 /pipelines.py: 项目管道文件
(5)SpiderNO1 /settings.py: 项目配置文件
(6)SpiderNO1 /spiders: 放置spider的目录
第二步:定义Item容器
- Item是保存爬取到的内容的容器,其使用方法和python字典类似,并且提供了额外的保护机制来避免拼写错误导致的未定义字段错误。
- 然后是对自己需要的数据进行建模。编辑SpiderNO1中的items.py
class DmozItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field() #标题
link = scrapy.Field() #链接
desc = scrapy.Field() #描述
保存关闭
第三步:编写爬虫
- 编写Spider,Spider是用户编写用于从网站上爬取数据的类,其中包含用于下载的初始URL,然后是如何跟进网页中的链接以及如何分析页面中的内容,还有提取item的方法。
- 创建一个名为“dmoz_spider.py”的文件
import scrapy
class DmozSpider(scrapy.Spider):
name = "dmoz" #蜘蛛编号,唯一
allowed_domains = [' http://www.dmoztools.net'] #蜘蛛爬取的范围
start_urls = ['http://www.dmoztools.net/Computers/Programming/Languages/Python/Books/',
'http://www.dmoztools.net/Computers/Programming/Languages/Python/Resources/'] #爬取网址
def parse(self,response): #定义分析方法
filename = response.url.split("/")[-2]
with open(filename,'wb') as f:
f.write(response.body)
接下来试一试蜘蛛能不能正常工作:
在cmd中进入工程SpiderNO1文件夹,输入命令scrapy crawl dmoz
我这里出了问题,报错

ModuleNotFoundError:No module named ‘win32api’
只需要用pip安装一下 pypiwin32即可

...

出现

并且同时在项目文件夹中产生了

两个文件,打开后发现是两个网页的审查元素代码。
以上就是“爬”的过程
之后就是从上面生成的Books文件和Resources文件中找出title、link、desc然后分别保存起来。
提取过程使用一种基于XPath和CSS的表达式机制:Scrapy Selectors。
Selectors是一个选择器,它有四个基本方法:
(1) xpath()——传入xpath表达式,返回该表达式所对应的所有节点的selector list列表。
(2) css()——传入CSS表达式,返回该表达式所对应的所有节点的selector list列表。
(3) extract()——序列化该节点为unicode字符串并返回list
(4) re()——根据传入的正则表达式对数据进行提取,返回unicode字符串list列表
在cmd中进入根文件夹,运行指令
scrapy shell “http://www.dmoztools.net/Computers/Programming/Languages/Python/Books/”
结果为以下代码

此时就得到了response的回应,就可以通过shell对其进行操作,如response.body就是全部网页的代码,response.headers就是网页的头,接下来通过selector选择器,对body中的内容进行分析提取,将用到
response.selector.xpath()
response.selector.css()
response.selector.extract()
response.selector.re
()这四个方法
XPath
XPath是一门在网页中查找特定信息的语言,用它来筛选数据更准确方便高效。
/html/head/title——选择HTML文档中<head>标签内的<title>元素。
/html/head/title/text()——选择上面提到的<title>元素的文字
//td——选择所有的<td>元素。
//div[@class=“mine”]——选择所有具有class=“mine”属性的div元素
在cmd中继续输入
response.xpath(‘//title’)
返回一个selector对象的列表

使用
response.xpath(‘//title’).extract()
将列表字符串化

不想要(title)的标签,就加入/text()就可以,即
response.xpath('//title/text()').extract()
第四步:提取数据
1、 由网页审查元素可知,

我们要提取的所有信息全都在在class=“title-and-desc”的标签中,描述在其/div中,链接在a标签href中,标题在a标签的div中。
标题:在shell中输入
response.xpath('//div[@class=" title-and-desc"]/a/div/text()').extract()
得到所有的标题,如下图(sel.xpath也可以得到下图)

描述:在shell中输入
response.xpath(‘//div[@class=” title-and-desc ”]/div/text()’).extract()
得到所有的描述,如下图(sel.xpath也可以得到下图)

…
链接:在shell中输入
response.xpath(‘//div[@class=”title-and-desc”]//a/@href’).extract()
得到所有的链接,如下图(sel.xpath也可以得到下图),提取a标签下的href标签需要使用@href

使用for循环依次打印title
sites = sel.xpath(‘//div[@class=”title-and-desc”]’)
for site in sites:
title = site.xpath(‘a/div/text()’) .extract()
link = site.xpath(‘a/@href’) .extract()
desc = site.xpath(‘div/text()’) .extract()
print(title,link,desc)

验证成功,把它放回dmoz_spider.py的parse()方法
def parse(self,response):
sel = scrapy.selector.Selector(response) #shell帮我们初始化好sel,这里我们需要自己将其初始化
sites = sel.xpath('//div[@class="title-and-desc"]')
for site in sites:
title = site.xpath('a/div/text()').extract()
link = site.xpath('a/@href').extract()
desc = site.xpath('div/text()').extract()
print(title,link,desc)
在cmd中运行scrapy crawl dmoz
如果报错

把循环体内的语句空格删掉,重新换行即可
正常运行结果(部分运行图):

可见我们需要的东西全部找出来了。
第五步:存储最后的结果
使用之前提到的item容器,将爬取的结果进行存储。
Spider代码为:
import scrapy
from SpiderNO1.items import DmozItem
#导入items
class DmozSpider(scrapy.Spider):
name = "dmoz"
allowed_domains = ['www.dmoztools.net']
start_urls = ['http://www.dmoztools.net/Computers/Programming/Languages/Python/Books/'
,'http://www.dmoztools.net/Computers/Programming/Languages/Python/Resources/']
def parse(self,response):
#shell帮我们初始化好sel,这里我们需要自己将其初始化
sel = scrapy.selector.Selector(response)
sites = sel.xpath('//div[@class="title-and-desc"]')
items = []
for site in sites:
item = DmozItem()
item['title'] = site.xpath('a/div/text()').extract()
item['link'] = site.xpath('a/@href').extract()
item['desc'] = site.xpath('div/text()').extract()
items.append(item)
return items
在cmd中使用
scrapy crawl dmoz –o items.json –t json
导出JSON格式文件
-o后面是文件名 –t指定导出类型
之后在根目录下就会出现items.json的文件


至此一个简单的爬虫就结束啦!
本博客所有文章均为作者原创,享有版权所有权,未经许可,严禁转载或修改!
网友评论