目录
创建新项目
怎么用scrapy
scrapy 一个完整的案例应用
css选择器介绍
css选择器的基本语法
scrapy 中的css使用方法
0
下载 scrapy
pip install scrapy
该命令先依据 项目名 创建一个文件夹,然后再文件夹下创建于个 scrpy
项目,这一步是后续所有代码的起点。
scrpy startproject <项目名>
创建新项目
scrapy startproject my_scrapy
创建第一个 scrapy
爬虫文件 pm
scrapy genspider pm imspm.com
如果想要运行项目命令,则必须先进入红色下划线 my_scrapy
文件夹,在项目目录中才能控制项目。
cd my_scrapy
此时在 spiders
文件夹中,出现 pm.py
文件,该文件内容如下所示:
import scrapy
class PmSpider(scrapy.Spider):
name = 'pm'
allowed_domains = ['imspm.com']
start_urls = ['http://imspm.com/']
def parse(self, response):
pass
测试 scrapy 爬虫运行
使用命令 scrapy crawl
,spider
是上文生成的爬虫文件名,出现如下内容,表示爬虫正确加载。
2022-11-12 15:27:02 [scrapy.utils.log] INFO: Scrapy 2.6.2 started (bot: my_scrapy)
scrapy
工作流程非常简单:
scrapy
一个完整的案例应用> scrapy startproject my_project 爬虫
> cd 爬虫
> scrapy genspider pm imspm.com
获得项目结构如下:
scrapy.cfg
:配置文件路径与部署配置;items.py
:目标数据的结构;middlewares.py
:中间件文件;pipelines.py
:管道文件;settings.py
:配置信息。代码请求次数为 7 次,原因是在 pm.py
文件中默认没有添加 www
,如果增加该内容之后,请求次数变为 4。
现在的 pm.py
文件代码如下所示:
import scrapy
class PmSpider(scrapy.Spider):
name = 'pm'
allowed_domains = ['www.imspm.com']
start_urls = ['http://www.imspm.com/']
def parse(self, response):
print(response.text)
其中的 parse
表示请求 start_urls
中的地址,获取响应之后的回调函数,直接通过参数 response
的 .text
属性进行网页源码的输出。
获取到源码之后,要对源码进行解析与存储
在存储之前,需要手动定义一个数据结构,该内容在 items.py
文件实现,对代码中的类名进行了修改,MyProjectItem
→ ArticleItem
。
import scrapy
class ArticleItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
title = scrapy.Field() # 文章标题
url = scrapy.Field() # 文章地址
author = scrapy.Field() # 作者
修改 pm.py
文件中的 parse
函数,增加网页解析相关操作,该操作类似 pyquery
知识点,直接观察代码即可掌握。
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for item in list_item:
title = item.css('.title::text').extract_first() # 直接获取文本
url = item.css('.a_block::attr(href)').extract_first() # 获取属性值
author = item.css('.author::text').extract_first() # 直接获取文本
print(title, url, author)
其中 response.css
方法返回的是一个选择器列表,可以迭代该列表,然后对其中的对象调用 css
方法。
item.css('.title::text')
,获取标签内文本;item.css('.a_block::attr(href)')
,获取标签属性值;extract_first()
:解析列表第一项;extract()
:获取列表。在 pm.py
中导入 items.py
中的 ArticleItem
类,然后按照下述代码进行修改:
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for i in list_item:
item = ArticleItem()
title = i.css('.title::text').extract_first() # 直接获取文本
url = i.css('.a_block::attr(href)').extract_first() # 获取属性值
author = i.css('.author::text').extract_first() # 直接获取文本
# print(title, url, author)
# 对 item 进行赋值
item['title'] = title
item['url'] = url
item['author'] = author
yield item
此时在运行 scrapy
爬虫,就会出现如下提示信息。
此时完成了一个单页爬虫
接下来对 parse
函数再次改造,使其在解析完第 1 页之后,可以解析第 2 页数据。
def parse(self, response):
# print(response.text)
list_item = response.css('.list-item-default')
# print(list_item)
for i in list_item:
item = ArticleItem()
title = i.css('.title::text').extract_first() # 直接获取文本
url = i.css('.a_block::attr(href)').extract_first() # 获取属性值
author = i.css('.author::text').extract_first() # 直接获取文本
# print(title, url, author)
# 对 item 进行赋值
item['title'] = title
item['url'] = url
item['author'] = author
yield item
next = response.css('.nav a:nth-last-child(2)::attr(href)').extract_first() # 获取下一页链接
# print(next)
# 再次生成一个请求
yield scrapy.Request(url=next, callback=self.parse)
上述代码中,变量 next
表示下一页地址,通过 response.css
函数获取链接,其中的 css
选择器请重点学习。
class="box"
表示选取class为box的元素;id="box"
表示选取id为box的元素;*[title]
表示选择所有包含title
属性的元素、a[href]
表示选择所有带有href属性的a元素等;li a
表示选取所有li 下所有a元素;h1 > strong
表示选择父元素为h1 的所有 strong 元素;以a元素来举例说明
response.css('a')
:返回的是selector对象;response.css('a').extract()
:返回的是a标签对象;response.css('a::text').extract_first()
:返回的是第一个a标签中文本的值;response.css('a::attr(href)').extract_first()
:返回的是第一个a标签中href属性的值;response.css('a[href*=image]::attr(href)').extract()
:返回所有a标签中href属性包含image的值;response.css('a[href*=image] img::attr(src)').extract()
:返回所有a标签下image标签的src属性;yield scrapy.Request(url=next, callback=self.parse)
表示再次创建一个请求,并且该请求的回调函数是 parse
本身,代码运行效果如下所示。
如果想要保存运行结果,运行下面的命令即可。
scrapy crawl pm -o pm.json
如果想要将每条数据存储为单独一行,使用如下命令即可 scrapy crawl pm -o pm.jl
。
生成的文件还支持 csv 、 xml、marchal、pickle ,可自行尝试。
下面将数据管道利用起来
打开 pipelines.py
文件,修改类名 MyProjectPipeline
→ TitlePipeline
,然后编入如下代码:
class TitlePipeline:
def process_item(self, item, spider): # 移除标题中的空格
if item["title"]:
item["title"] = item["title"].strip()
return item
else:
return DropItem("异常数据")
该代码用于移除标题中的左右空格。
编写完毕,需要在 settings.py
文件中开启 ITEM_PIPELINES
配置。
ITEM_PIPELINES = {
'my_project.pipelines.TitlePipeline': 300,
}
300
是 PIPELINES
运行的优先级顺序,根据需要修改即可。再次运行爬虫代码,会发现标题的左右空格已经被移除。
到此 scrapy 的一个基本爬虫已经编写完毕。
python - 爬虫Scrapy框架之css选择器使用 0