简介
本人现在是一个学生,平时主要用的是Java,业余时间学习了Python,在提高自己的同时,想把自己学习过程记录下来,希望可以帮到更多入门的同学们。
所使用到的工具
PyCharm
Python3.6
Scrapy
创建一个scrapy项目
在你的工作目录的文件夹下打开命令提示符窗口,输入:
scrapy startproject demo
如果出现下面的提示,则说明创建成功。
使用PyCharm打开这个scrapy项目,它的目录结构是这样的:
scrapy.cfg文件中主要包含的是项目的相关设置。
demo文件夹下是用于编写爬虫的目录。
items.py:定义我们所要爬取的信息的相关属性。
middlewares.py:爬虫中间件,这里可以用过自定义相关的方法,用来处理爬虫的响应和请求。
pipelines.py:当数据被爬虫爬取下来后,它会被发送到item pipelines中,每个item pipelines组件(有时称为“项目管道”)是一个实现简单方法的Python类。他们收到一个项目并对其执行操作,还决定该项目是否应该继续通过管道或被丢弃并且不再被处理。
settings.py:项目的设置文件。
编写代码
在spiders文件夹下创建douban_spider.py文件
这是一个空的.py文件,然后在这编写爬虫代码。
# 爬虫类需要继承scrapy下的Spider类。
import scrapy
class douban_movie_spider(scrapy.Spider):
# 项目的启动名
name = "douban_movie"
# 如果网站设置有防爬措施,需要添加上请求头信息,不然会爬取不到任何数据
headler = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 '
'Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
}
# 开始链接
start_urls = [
'https://movie.douban.com/top250'
]
# start_requests方法为scrapy的方法,我们对它进行重写。
def start_requests(self):
# 将start_url中的链接通过for循环进行遍历。
for url in self.start_urls:
# 通过yield发送Request请求。
# 这里的Reques注意是scrapy下的Request类。注意不到导错类了。
# 这里的有3个参数:
# 1、url为遍历后的链接
# 2、callback为发送完请求后通过什么方法进行处理,这里通过parse方法进行处理。
# 3、如果网站设置了防爬措施,需要加上headers伪装浏览器发送请求。
yield scrapy.Request(url=url, callback=self.parse, headers=self.headler)
# 重写parse对start_request()请求到的数据进行处理
def parse(self, response):
pass
页面分析
打开https://movie.douban.com/top250,点击f12开发者工具。
使用选取工具选取整个电影的信息,可以发现,所有的信息都是放在单独的一个li标签中的,而且在li下还有一个class为item的div包裹着所有的信息。
parse方法
def parse(self, response):
# 这里使用scrapy的css选择器,既然数据在class为item的div下,那么把选取范围定位div.item
for quote in response.css('div.item'):
# 通过yield对网页数据进行循环抓取,我们要抓取的内容有3个,分别如下
yield {
"电影名": quote.css('div.info div.hd a span.title::text').extract_first(),
"评分":quote.css('div.info div.bd div.star span.rating_num::text').extract(),
"引言": quote.css('div.info div.bd p.quote span.inq::text').extract()
}
写完上面的代码,其实只是抓取一页的罢了,为了抓取完整的top250榜单,我们需要让爬虫跳转到下一页再进行循环抓取,因为每个页面的结构是一样的,所以不用担心会抓取不到。
next_url=response.css('div.paginator span.next a::attr(href)').extract()
然后,需要对next_url进行判断是否存在,然后再次发送Request请求。这样爬虫就会在爬完一个页面后点击下一页再继续爬去,往复循环,直到爬取完毕。
if next_url:
next_url="https://movie.douban.com/top250"+next_url[0]
print(next_url)
yield scrapy.Request(next_url,headers=self.headler)
那么到这里,代码就写完了。
然后我们来运行一下这个爬虫,scrapy框架是通过命令来启动爬虫的,
在项目根目录下打开命令提示符,输入:
scrapy crawl douban_movie -o douban_movice.csv
scrapy会把爬取到的结果保存到douban_movice.csv这个文件里。
爬虫运行后,就会输出大量的日志信息和爬去的网页的内容。
数据会保存在douban_movice.csv这个文件中。
但是,有个问题,如果爬虫报错了怎么办?
因为使用命令启动的爬虫,所以爬虫的日志信息都是显示在cmd中的,这样日志信息阅读起来非常的不友好。所以我们需要写一个启动爬虫的python脚本,这样日志信息就会输出在python环境下了
新建一个run.py文件,代码如下:
from scrapy import cmdline
name='douban_movie -o douban.csv'
cmd = 'scrapy crawl {0}'.format(name)
cmdline.execute(cmd.split())
然后运行这个文件,所以的日志信息就输出在Python环境下,便于调试。
运行得到的结果都是一样的。
完整的代码是这样的:
import scrapy
class douban_movie_spider(scrapy.Spider):
name = "douban_movie"
headler = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/56.0.2924.87 '
'Safari/537.36',
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8'
}
start_urls = [
'https://movie.douban.com/top250'
]
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(url=url, callback=self.parse, headers=self.headler)
def parse(self, response):
for quote in response.css('div.item'):
yield {
"电影名": quote.css('div.info div.hd a span.title::text').extract_first(),
"评分":quote.css('div.info div.bd div.star span.rating_num::text').extract(),
"引言": quote.css('div.info div.bd p.quote span.inq::text').extract()
}
next_url=response.css('div.paginator span.next a::attr(href)').extract()
if next_url:
next_url="https://movie.douban.com/top250"+next_url[0]
print(next_url)
yield scrapy.Request(next_url,headers=self.headler)
好了,本教程到此结束。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。