scrapy爬取QQ音乐榜单歌曲及豆瓣电影信息。
系列文章目录
第三章 scrapy爬取QQ音乐榜单歌曲及豆瓣电影信息。
目录
前言
这次要爬取的两个项目分别使用了JavaScript和Ajax。因为二者的语法很相似所以写到一片博客里面。也可以更方便的进行对比。
一、scrapy爬取QQ音乐榜单歌(JavaScript)
1.项目需求
目标网址:https://y.qq.com/n/yqq/toplist/4.html。
现要将榜单中的歌曲信息爬取下来,字段有:歌曲名称、唱片、歌手和时长。
2.项目分析
通过控制台分析发现,具体信息并不存储在静态html信息之中。
所以要去javascript中寻找相应的信息存储文件。
博主之前写代码时存储信息还在javascript,但现在已经被隐藏了,但是博主的爬虫还能正常运行,所有直接给大家把网址贴出来。正常情况应该大家在js文件中自己寻找。
https://c.y.qq.com/v8/fcg-bin/fcg_v8_toplist_cp.fcg?&topid=4
大家可以看到这个信息非常的凌乱根本无法直接提前信息,这个时候就需要用的json格式化,百度直接搜就可以,但博主还是吧网址贴出来。json在线格式化。
进入后将目标文件源代码粘贴进去,点击格式化校验。
仔细观察可以发现,json编码只有两种类型,类似于python的字典和列表,这样就可以和分析html静态页面一样进行数据抓取了。
我们所需要的信息都存在一个叫songlist的列表中,其中的每一个元素都是以字典的形式存在的。
3.代码编写
1.编写item(数据封装)
import scrapy
class QqmusicItem(scrapy.Item):
song_name=scrapy.Field() #歌曲
album_name = scrapy.Field() #唱片
singer_name = scrapy.Field() #歌手
interval = scrapy.Field() #时长
2.编写spider(数据抓取(核心代码))
from scrapy import Request
from scrapy.spiders import Spider
from ..items import QqmusicItem
import json #引入json库
class MusicSpider(Spider):
name = "music"
pass
def start_requests(self):
url="https://c.y.qq.com/v8/fcg-bin/fcg_v8_toplist_cp.fcg?&topid=4"
yield Request(url)
def parse(self, response,):
json_text=response.text #json格式化
music_dict=json.loads(json_text) #加载json文件
for one_music in music_dict["songlist"]:
item=QqmusicItem()
#获取歌曲名称
item["song_name"]=one_music["data"]["songname"]
#获取唱片
item["album_name"] = one_music["data"]["albumname"]
#获取歌手
item["singer_name"] = one_music["data"]["singer"][0]["name"]
#获取市场
item["interval"] = one_music["data"]["interval"]
yield item
3.编写settings(项目配置)
伪装浏览器,不遵循robots协议
4.start.py(代替命令行)
在爬虫项目文件夹下创建start.py。
运行之后生成csv文件。
二、scrapy爬取豆瓣电影信息(Ajax)
1.项目需求
将中国大陆的电影信息爬取下来,字段有:电影名称、导演、演员和评分。
目标url:https://movie.douban.com/tag/#/?sort=U&range=0,10&tags=电影,中国大陆
信息类型可根据需要自行修改。
2.项目分析
在控制台分析发现,信息是采用Ajax局部动态刷新技术实现的。
当我们将页面拉到最下方发现,需要手动获取新的内容。点击加载更多。
之后便出现了新的Ajax文件。
进行url分析。
https://movie.douban.com/j/new_search_subjects?sort=U&range=0,10&tags=电影&start=0&countries=中国大陆
https://movie.douban.com/j/new_search_subjects?sort=U&range=0,10&tags=电影&start=20&countries=中国大陆
对比发现只有start的属性值发生了变化而且是以20为单位进行递增。
所以只需要挨个访问相应的url进行数据抓取就可以了。
但是相应的文件内容也仍然很凌乱。
这里我们依旧使用json格式化。
这里依旧只有列表和字典两种形式。都存储在data中。依次抓取信息即可
3.代码编写
1.编写item(数据封装)
import scrapy
class DoubanItem(scrapy.Item):
title = scrapy.Field() #电影名称
dicectors = scrapy.Field() # 导演
casts = scrapy.Field() # 演员
rate = scrapy.Field() # 评分
2.编写spider(数据抓取(核心代码))
#coding:utf-8
from scrapy import Request
from scrapy.spiders import Spider
from ..items import DoubanItem
import json
import time
class DoubanSpider(Spider):
name = "movies"
current_page=1 #起始页面
def start_requests(self):
url="https://movie.douban.com/j/new_search_subjects?tags=电影&start=0&countries=中国大陆"
yield Request(url)
pass
def parse(self, response):
item=DoubanItem()
json_text=response.text
movie_dict=json.loads(json_text)
if len(movie_dict["data"])==0:
return
else:
for one_movie in movie_dict["data"]:
#获取电影名称
item["title"]=one_movie["title"]
# 获取导演
item["dicectors"] = one_movie["directors"]
# 获取演员
item["casts"] = one_movie["casts"]
# 获取评分
item["rate"] = one_movie["rate"]
yield item
#爬取更多
next_url="https://movie.douban.com/j/new_search_subjects?tags=电影&start=%d&countries=中国大陆"%(self.current_page*20)
self.current_page+=1
time.sleep(1) #等待一秒,防止IP被封
yield Request(url=next_url)
3.编写settings(项目配置)
伪装浏览器,不遵循robots协议
4.start.py(代替命令行)
在爬虫项目文件夹下创建start.py。生成scv文件。
运行项目会出现一个报错。
这是因为咱们只设置了项目的开始,并没有设置项目的结束,到最后访问不到新的Ajax就会出现这个错误但并不影响项目整个的效果。
总结
此次将javascript和Ajax放到了一起,主要是因为二者的访问方法和编码方法很类似,一次性讲解可以省很多时间。