目录
一、什么是爬虫
- 爬虫即为数据爬取
数据来源
- 从网上爬取数据(crawling)
- 从本地系统收集数据(scraping):文件、数据库等
网络数据采集模型
二、常用的数据爬取工具
第三方库实现爬取
- Requests、lxml:灵活,简单
PySpider爬虫框架
- 提供WebUI界面编写及管理爬虫
- 上手快,学习简单
- 对Windows操作系统支持很差
Scrapy爬虫框架
- 功能强大
- 可定制性强
- 多线程,爬取效率高
三、使用Scrapy框架
准备工作:需要已安装Anaconda、PyCharm,没有安装的可以参考下面这篇文章
https://blog.csdn.net/weixin_38468167/article/details/113174379
安装配置
第一步:下载安装
- 在windows命令行执行:
conda install scrapy
第二步:配置Scrapy的环境变量
- 找到Anaconda的所在位置
- 找到Scripts目录
- 将这个目录路径添加到环境变量的Path中
- 配置完成后在windows命令行输入scrapy查看信息
这样表示scrapy已经安装成功了
创建Scrapy工程
-
新建一个期望存放Scrapy项目的文件夹
-
然后在那个文件夹路径框内输入cmd回车
-
在windows命令行输入:
scrapy startproject [新工程名]
-
然后会在目录下产生一个目录文件
使用PyCharm打开Scrapy工程
-
打开工程前需要先设置python解释器
-
打开项目
-
选择工程所在的路径
-
打开后查看spiders目录下的文件
import scrapy
class ExamplespiderSpider2(scrapy.Spider):
name = 'exampleSpider2'
allowed_domains = ['example.com']
start_urls = ['http://www.qq.com'] #指定一个合法的可访问的地址
def parse(self, response):
print("start parse") #这里不做任何处理,直接输出start parse
-
启动Spider:命令格式
scrapy crawl 爬虫名
-
可以看到start parse就表示工程与环境没有问题了
使用Python脚本执行命令行启动工程
- 在项目根目录添加脚本文件
- 调用Scrapy框架的命令行执行方法启动爬虫
cmdline模块
execute()方法
示例:
- 在工程根目录下创建run.py
- 在run.py中输入命令
from scrapy.cmdline import execute
execute('scrapy crawl example_spider'.split())
- 右集run.py文件,点击运行
- 同样可以运行出结果
四、Scrapy框架以及使用
spiders文件夹
- 定义爬虫文件
items.py
- 定义框架内数据传输格式
pipelines.py
- 数据保存模块
middlewares.py
- 中间件模块
settings.py
- 框架配置模块
Scrapy返回爬取页面数据
通过解析方法返回爬取页面数据
- parse()方法的response参数
- response对象常用属性和方法
在Scrapy爬虫框架中提取网页数据的方法
xpath选择器
- 用于选择XML文档中的节点的语言,可以与HTML一起使用
css选择器
- 用于将样式应用于HTML文档的语言
- 将样式与特定的HTML元素相关联
正则表达式
- 提取非标签内容
xpath语法
- 使用路径表达式来选取 XML 文档中的节点或节点集
谓语
- 谓语用来查找某个特定节点或者包含某个指定的值的节点
- 谓语被嵌在方括号中
选择器
-
Scrapy中xpath选择器
基于lxml库 -
获取选择器的网页数据
extract()
提取selector列表中的网页数据
如果列表为空,取下标为0的网页数据会抛出异常
extract_first()
提取selector列表中下标为0的网页数据
如果列表为空,不会抛出异常,返回None
路径表达式举例
爬取从页面提取的URL
使用场景
- 详情页爬取
- 多层级目录爬取
提取URL发起HTTP请求
- 构造request对象
指定HTTP请求的URL
指定处理这个页面的回调方法 - 关闭去重标记
使用yield返回request对象
request与对应的response传递数据
- meta字典
Scrapy的item模块
item的作用
- 定义框架中数据传输的形式
定义item
- 定义Item类并继承scrapy.Item
- 定义变量
变量名
变量类型
scrapy.Field()
使用item
- 使用字典的方式给item赋值
item[“变量名”] = 赋值
使用yield返回item
将爬取数据保存到文件中
Feed exports
- 将数据导出成常用数据格式的方法
默认支持的格式
- JSON
- JSON lines
- CSV
- XML
使用Feed exports的方法
- 在命令行中使用-o来调对应的Feed exports
- 在settings.py中配置Feed exports
FEED_FORMAT = 'CSV'
FEED_URI ='quotes.csv'
五、示例
示例网站
继续开始创建的工程中操作
设置items.py
# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.html
import scrapy
class Scrapyproject01Item(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field()
#指定需要接收的数据变量
quote=scrapy.Field()
author_name=scrapy.Field()
author_born_date=scrapy.Field()
author_born_loc=scrapy.Field()
author_desc=scrapy.Field()
#pass
设置setting.py
#在setting.py中的最下面设置保存的文件格式与文件名
FEED_FORMAT = 'csv'
FEED_URI = 'result2.csv'
逻辑实现examplespiderSpider
- 在examplespiderSpider中编写具体逻辑代码
import scrapy
#导包(与java稍有不同,这里需要将导包所在的路径指出)
from ..items import Scrapyproject01Item
class ExamplespiderSpider(scrapy.Spider):
name = 'exampleSpider3'
allowed_domains = ['example.com']
#指定目标地址
start_urls = ['http://quotes.toscrape.com']
#self:类似于java中的this
#response:从目标地址获取到数据都在这里
def parse(self, response):
print("start parse")
#拿到网页数据过滤出所有div为quote的所有数据
quotes = response.xpath("//div[@class='quote']")
#网页中存在多个div类名为quote,遍历一下
for quote in quotes:
#对每个div名为quote内的数据进一步过滤,并且只要拿到第一条,如果只用extract,如果没有拉取到数据就会报错
quote_text=quote.xpath("./span[@class='text']/text()").extract_first()
#然后在过滤出作者信息的路径
quote_author_url = quote.xpath(".//a/@href").extract_first()
#爬取新的目标地址,进入作者的详情页
#第一个参数为新的目标地址,我们通过原先的地址拼接过滤出的路径即可
#callback:因为操作的页面变了,逻辑也会不同,所有需要自定义方法,这里就指定了自定义的方法
#dont_filter:设置不屏蔽处理过的目标地址
#mate:设置字典,保存获取到的quote_text的数据
yield scrapy.Request(self.start_urls[0]+quote_author_url,
callback=self.parse_author_detail,
dont_filter=True,
meta={"quote":quote_text})
#获取下一页的路径
next_page = response.xpath("//li[@class='next']/a/@href").extract_first()
#判断是否还有下一页
if next_page is not None:
#将获取的下一页路径与原目标地址进行拼接
next_page2 = self.start_urls[0] + next_page
#爬取新的目标地址,默认调用parse方法
yield scrapy.Request(next_page2,dont_filter=True)
#自定义方法,用于处理爬取的作者详情页的数据
def parse_author_detail(self,reponse):
#注意创建items下的类对象时要带括号()
item=Scrapyproject01Item()
#在item中预先设置好需要的变量
#将字典中的quote的数据传入item对象中
item['quote']=reponse.meta["quote"]
#过滤出作者的姓名,传入至对象item中
item['author_name'] = reponse.xpath("//h3[@class='author-title']/text()").extract_first().strip().strip("\n")
#过滤出作者的生日,传入至对象item中
item['author_born_date'] = reponse.xpath("//span[@class='author-born-date']/text()").extract_first().strip().strip("\n")
#过滤出做的地址,传入至对象item中
item['author_born_loc'] = reponse.xpath("//span[@class='author-born-location']/text()").extract_first().strip().strip("\n")
#过滤出作者介绍信息,传入至对象item中
item['author_desc'] = reponse.xpath("//div[@class='author-description']/text()").extract_first().strip().strip("\n").replace("\n"," ")
yield item
设置run.py
#运行命令
from scrapy.cmdline import execute
execute("scrapy crawl exampleSpider".split())
执行
-
运行run.py文件
-
成功创建出文件
-
打开result2
- 这里就完成了简单的爬取功能