文章目录
- 1. scrapy介绍
- 2 新建爬虫项目
- 3 新建蜘蛛文件
- 4 运行爬虫
- 5 爬取内容
- 5.1分析网页结构
- 5.2 关于Xpath解析
- 5.3 接着解析电影数据
- 5.4 下载缩略图
- 5.5 完整代码
- 6 最后说明
本例基于python3和scrapy爬虫框架,不再介绍python的基础知识和爬虫的基本知识。
1. scrapy介绍
Scrapy是适用于Python的一个快速、高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。
首先安装scrapy:
pip3 install scrapy
2 新建爬虫项目
scrapy startproject pic
项目目录如下:
3 新建蜘蛛文件
蜘蛛文件放在spiders目录下,在spiders目录下新建一个蜘蛛文件pic.py
,内容如下,并没有设计爬取操作,代码比较简单,看代码中的注释就明白了:
import scrapy#类名自定义,参数固定为scrapy.Spider
class GetImage(scrapy.Spider):name="pic" #蜘蛛名称,必须唯一,一个爬虫项目可以新建多个蜘蛛文件,蜘蛛名不能重复def start_requests(self):#定义要爬取的url urls=['https://www.rottentomatoes.com/browse/movies_in_theaters/']#请求网页内容,并将内容交给回调函数处理for url in urls:# yield关键字类似return,scrapy.Request发起网页请求,括号内为参数,第一个参数是Request要请求的地址,第二个参数是回调函数,表示Request取到的内容交由该回调函数处理。yield scrapy.Request(url=url,callback=self.parse) #上一方法需要调用的回调函数def parse(self,response):print("------------------------")#此处获取上一步请求的网页内容及请求状态,print(response.body)可以获取网页内容,#因为内容太长,这里不再输出,只输出地址和状态。print(response)
4 运行爬虫
回到项目的根目录,运行如下命令:
scrapy crawl pic # crawl指定类文件中定义的蜘蛛名称pic
可以在运行日志中查看结果,200是网页连接正常的状态码:
5 爬取内容
上面代码中的网址是烂番茄网的电影页面,建议在测试时尽量选择测试网站进行测试,爬取信息时请遵守网站规定,并确认是否允许爬取.示例中的网页如下图所示:
5.1分析网页结构
我们的目标是所有电影的名称和缩略图,首先通过F12查看网页的结构及目标节点的样式,如下图所示:
可以看到只要找
tile-dynamic
节点下的img
标签即可。scrapy中获取节点如下所示:
运行爬虫,获取到的电影名称如下所示,是一个列表:
5.2 关于Xpath解析
此处展示一些Xpath用法:
#从html根节点查找最外层所有divdivs = response.xpath('//div')#从html根节点查找第一个divdiv = response.xpath('//div[1]')#从上面的div中查找所有p节点,注意此时开头用./不是//ps = div.xpath('./p')#从上面的div中查找所有样式为col-4的p节点ps1 = div.xpath('./p[@class="col-4"]')#循环获取ps1中所有p节点下的img图像地址for p in ps1:#获取节点属性以@开头如@alt,@src,@text等srcs = p.xpath('./img/@src').get() #或者getall(),p节点包含多张图片的情况#更多xpath请参考官方教程:#https://docs.scrapy.org/en/latest/topics/selectors.html#working-with-xpaths
5.3 接着解析电影数据
增加对缩略图的抓取,代码获取的缩略图如下图所示:
5.4 下载缩略图
下载过程如图所示:
下载内容:
5.5 完整代码
import scrapy
import ssl
import os
import urllib#定义图片下载地址,请修改为自己的路径
d_path = '/home/ubuntu/下载/albums'#类名自定义,参数固定为scrapy.Spider
class GetImage(scrapy.Spider):name="pic" #蜘蛛名称,必须唯一,一个爬虫项目可以新建多个蜘蛛文件,蜘蛛名不能重复def start_requests(self):#定义要爬取的url urls=['https://www.rottentomatoes.com/browse/movies_in_theaters/']#请求网页内容,并将内容交给回调函数处理for url in urls:# yield关键字类似return,scrapy.Request发起网页请求,括号内为参数,第一个参数是Request要请求的地址,第二个参数是回调函数,表示Request取到的内容交由该回调函数处理。yield scrapy.Request(url=url,callback=self.parse) #上一方法需要调用的回调函数def parse(self,response):print("--------------------------")#此处获取上一步请求的网页内容及请求状态,print(response.body)可以获取网页内容,#因为内容太长,这里不再输出,只输出地址和状态。print(response)#获取页面所有电影节点#xpath方式获取 //表示从页面根节点开始查找,查找tile-tynamic下的img标签#然后获取img标签下的alt属性,这里alt属性是电影的名字。#getall()表示获取所有匹配项,get()获取第一个匹配项names = response.xpath('//tile-dynamic/img/@alt').getall()#获取页面所有电影缩略图地址albums = response.xpath('//tile-dynamic/img/@src').getall()for index,album in enumerate(albums):#循环取出缩略图地址,交由函数downImg来完成图片下载#并传入参数name,用作下载的缩略图命名self.downImg(album,names[index])#图片下载方法def downImg(self,album,name):try:#下载图片,参数第一个是缩略图地址,第二个参数是文件保存地址+文件名称+后缀名urllib.request.urlretrieve(album,d_path+"/" + name + ".jpg")except Exception as e:print('下载异常:')print(e)passprint ('下载图片:' + name)
6 最后说明
一个简单的图片爬虫就完成了,一个功能复杂的爬虫,还需要解决登陆,分页,或者爬取到结果后入库等操作,这里就不多做解释,以后有空会更新登陆,分页等其他功能,没有空就不更新了。最后还要说明一点,爬取网络内容时请遵守相关法律法规,和网站规则。一般网站的根目录下都有robots.txt文件,请确保遵循了robots.txt的规则。比如烂番茄网
的robots.txt规则如下:
Disallow:/search 表示不允许爬取 /search下的所有网页。