抓取ajax动态网页java(爬虫Scrapy框架的原理架构图运作流程及案例分析(一))

优采云 发布时间: 2022-01-21 05:06

  抓取ajax动态网页java(爬虫Scrapy框架的原理架构图运作流程及案例分析(一))

  通过前七章的学习,相信大家对整个爬虫有了比较全面的了解,其中涉及到四个案例:静态网页爬取、动态Ajax网页爬取、Selenium浏览器模拟爬取和Fillder今日头条app爬取,基本上涵盖了爬虫的一般套路。在此基础上,本文进一步开发并使用Scrapy框架构建了一个更接近搜索引擎技术的QQ音乐分布式爬虫系统。

  

  一、前期准备

  1.Scrapy原理概述

  Scrapy 是一个应用程序框架,用于抓取 网站 数据并提取结构化数据。它可以用于一系列程序,包括数据挖掘、信息处理或存储历史数据。最初是为爬虫或者data采集设计的,也可以用来获取API或者一般网络爬虫返回的数据。总之,相比普通爬虫,Scrapy 是“有组织有纪律”的,更容易构建大型爬虫项目。

  下图是Scrapy框架的*敏*感*词*,一一讲解:

  

  有了上面Scrapy组件的介绍,下面介绍一下Scrapy的运行过程:

  爬虫使用yield向EngineEngine发送请求,对请求什么都不做,发送给SchedulerEngine获取请求,通过Middleware发送给DownloaderDownloader获取响应,再通过Middleware发送给EngineEngine Middleware 将其传递给 Spider,Spider 的 parse() 方法解析响应 Spider 会将解析后的 item 或 requests 返回到 EngineEngine,将 item 发送到 ItemPipeline,将请求发送到 Scheduler。仅当调度程序中没有请求时,程序才会停止。

  2.Scrapy安装配置

  接下来,安装 Scrapy。Scrapy 已经支持 python3。本文环境为win10+Anaconda3。实际安装没有问题。首先通过 pip 安装 Scrapy:

  pip install scrapy

  然后进入python命令行并导入。如果没有错误,则安装成功。

  import scrapy

  3.Scrapy 入门测试

  然后我们通过百度分布式爬虫框架的一个小例子进行测试。首先在cmd中使用cd命令切换到任意目录,然后运行:

  scrapy startproject littletest

  然后切换到项目目录,通过genspider命令添加爬虫网站:

  cd littletest

scrapy genspider baidu www.baidu.com

  然后进入目录查看,目录结构如下:

  

  同时我们进入settings.py,将ROBOTSTXT_OBEY配置项改为False,即不符合爬虫协议,否则很多网站无法正常获取。

  ROBOTSTXT_OBEY = False

  最后进入命令行启动scrapy爬虫:

  scrapy crawl baidu

  结果如下,状态码为200,接收字节数大于0,表示爬取成功!

  

  3.MongDB安装配置

  MongoDB 是目前最流行的 NoSQL 数据库之一。它使用数据类型 BSON(类似于 JSON)。下载、安装和配置,以及链接python的pymongo数据库和最好的指南针可视化工具,请参考作者博客的安装和使用。

  二、QQ音乐爬虫实战

  1.网页分析

  通过打开QQ音乐官网点击歌手栏目(链接传送门:),打开DevTools工具,选择XHR异步,观察项,发现musicu.fcg栏返回的json数据中收录歌手相关信息。

  

  因此,我们进一步输入headers获取请求url,继续点击下一页,通过三个页面(url如下)找到sin参数的变化找到规则,规则公式为80*( n-1),n为页码,篇幅有限,json数据解析就不解释了,请参考上一篇。

  https://u.y.qq.com/cgi-bin/musicu.fcg?-=getUCGI9874589974344781&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0&data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerList%22%3A%7B%22module%22%3A%22Music.SingerListServer%22%2C%22method%22%3A%22get_singer_list%22%2C%22param%22%3A%7B%22area%22%3A-100%2C%22sex%22%3A-100%2C%22genre%22%3A-100%2C%22index%22%3A-100%2C%22sin%22%3A0%2C%22cur_page%22%3A1%7D%7D%7D

https://u.y.qq.com/cgi-bin/musicu.fcg?-=getUCGI8205866038561849&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0&data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerList%22%3A%7B%22module%22%3A%22Music.SingerListServer%22%2C%22method%22%3A%22get_singer_list%22%2C%22param%22%3A%7B%22area%22%3A-100%2C%22sex%22%3A-100%2C%22genre%22%3A-100%2C%22index%22%3A-100%2C%22sin%22%3A80%2C%22cur_page%22%3A2%7D%7D%7D

https://u.y.qq.com/cgi-bin/musicu.fcg?-=getUCGI8189152987042585&g_tk=5381&loginUin=0&hostUin=0&format=json&inCharset=utf8&outCharset=utf-8¬ice=0&platform=yqq.json&needNewCode=0&data=%7B%22comm%22%3A%7B%22ct%22%3A24%2C%22cv%22%3A0%7D%2C%22singerList%22%3A%7B%22module%22%3A%22Music.SingerListServer%22%2C%22method%22%3A%22get_singer_list%22%2C%22param%22%3A%7B%22area%22%3A-100%2C%22sex%22%3A-100%2C%22genre%22%3A-100%2C%22index%22%3A-100%2C%22sin%22%3A160%2C%22cur_page%22%3A3%7D%7D%7D

  以此类推,获取歌曲下载地址、歌曲列表地址、歌词列表地址、歌曲评论地址等,并配置翻页参数:

  start_urls = ['https://u.y.qq.com/cgi-bin/musicu.fcg?data=%7B%22singerList%22%3A%7B%22module%22%3A%22Music.SingerListServer' \

'%22%2C%22method%22%3A%22get_singer_list%22%2C%22param%22%3A%7B%22area%22%3A-100%2C%22sex%22%3A-100%2C%22genr' \

'e%22%3A-100%2C%22index%22%3A-100%2C%22sin%22%3A{num}%2C%22cur_page%22%3A{id}%7D%7D%7D'] # 歌手地址

song_down = 'https://c.y.qq.com/base/fcgi-bin/fcg_music_express_mobile3.fcg?&jsonpCallback=MusicJsonCallback&ci' \

'd=205361747&songmid={songmid}&filename=C400{songmid}.m4a&guid=9082027038' # 歌曲下载地址

song_url = 'https://c.y.qq.com/v8/fcg-bin/fcg_v8_singer_track_cp.fcg?singermid={singer_mid}&order=listen&num={sum}' # 歌曲列表地址

lrc_url = 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric.fcg?nobase64=1&musicid={musicid}' # 歌词列表地址

discuss_url = 'https://c.y.qq.com/base/fcgi-bin/fcg_global_comment_h5.fcg?cid=205360772&reqtype=2&biztype=1&topid=' \

'{song_id}&cmd=8&pagenum=0&pagesize=25' # 歌曲评论地址

  之后我们开始构建scrapy爬虫。首先切换到个人目录打开项目:

  scrapy startproject musicspyder

cd musicspyder

scrapy genspider qqmusic y.qq.com

  2.spyder.py 写的

  接下来,开始对Scrapy组件进行一一完善。首先编写爬虫主程序qqmusic.py,在生成的类中定义爬虫名称、允许域名、爬取url等变量,并创建解析用户信息、歌曲信息、歌词信息、评论信息、url信息方法:

  import json

import scrapy

from scrapy import Request

from musicspyder.items import QqMusicItem

class MusicSpider(scrapy.Spider):

name = 'qqmusic'

allowed_domains = ['y.qq.com']

start_urls = ['...']

song_down = '...'

song_url = '...'

lrc_url = '...'

discuss_url = '...'

# 生成请求并从配置中获取页数

def start_requests(self):

# 解析用户信息

def parse_user(self, response)

# 解析歌曲信息

def parse_song(self, response)

# 解析歌词信息

def parse_lrc(self, response)

# 解析评论信息

def parse_comment(self, response)

# 解析url信息

def parse_url(self, response)

  3.items.py 写的

  然后编写items.py,在QqMusicItem类中创建MongoDB集合名称、id字段、歌手姓名字段、歌曲名称字段、歌曲地址字段、歌词字段、评论字段等变量:

  import scrapy

from scrapy import Field

class QqMusicItem(scrapy.Item):

# mongodb collection

collection = 'singer'

id = Field()

# 歌手名字字段

singer_name = Field()

# 歌曲名字段

song_name = Field()

# 歌曲地址字段

song_url = Field()

# 歌词字段

lrc = Field()

# 评论字段

comment = Field()

  由 4.piplines.py 编写

  然后编写piplines.py,并添加IrcText类来解析歌词:

  import json

import pymongo

import re

from scrapy.exceptions import DropItem

from musicspyder.items import QqMusicItem

# 默认pipline类

class QqMusicPipeline(object):

def process_item(self, item, spider):

return item

# 在pipline中新增类用于解析和清洗单词

class lrcText(object):

# 进行正则匹配获取的单词

def process_item(self, item, spider):

# 保存到Mongo数据库

class MongoPipline(object):

# 构造方法

def __init__(self, mongo_url, mongo_db):

# 从settings.py中获取Mongo rl和库

@classmethod

def from_crawler(cls, crawler):

# 存储处理

def process_item(self, item, spider):

# 关闭mongodb数据库

def close_spider(self, spider):

  之后,编写 middlewares.py 代码,自定义 my_useragent 类,使用 random 库随机选择浏览器头:

  import random

from scrapy import signals

# 默认中间件

class MusicspyderSpiderMiddleware(object):

@classmethod

def from_crawler(cls, crawler):

def process_spider_input(self, response, spider):

def process_spider_output(self, response, result, spider):

def process_spider_exception(self, response, exception, spider):

def process_start_requests(self, start_requests, spider):

def spider_opened(self, spider):

# 在中间件中加入useragent防爬

class my_useragent(object):

def process_request(self, request, spider):

user_agent_list = ['...','...',...]

user_agent = random.choice(user_agent_list)

request.headers['User_Agent'] = user_agent

  6.settings.py 编写

  最后编写settings.py,配置要爬取的页数、要爬取的歌曲数、mongoDB的地址和数据库等相应变量,并设置不符合Robots协议,并打开下载中间件和项目管道:

  # 系统配置变量

BOT_NAME = 'musicspyder'

SPIDER_MODULES = ['musicspyder.spiders']

NEWSPIDER_MODULE = 'musicspyder.spiders'

MAX_PAGE = 3 # 爬取页数

SONGER_NUM = 1 # 爬取歌手歌曲数量

MONGO_URL = 'mongodb://localhost:27017/'

MONGO_DB = 'music' # mongo数据库

# 定义robots协议遵守规则为:不遵守

ROBOTSTXT_OBEY = False

# 启用下载中间件

DOWNLOADER_MIDDLEWARES = {

# 'musicspyder.middlewares.QqMusicDownloaderMiddleware': 543,

'musicspyder.middlewares.my_useragent': 544,

}

# 启用pipline中mongodb存储

ITEM_PIPELINES = {

# 'musicspyder.pipelines.QqMusicPipeline': 300,

'musicspyder.pipelines.lrcText': 300,

'musicspyder.pipelines.MongoPipline': 302,

}

  定义好上述scrapy组件后,我们可以在命令行输入如下命令来开启qqmusic爬虫框架:

  scrapy crawl qqmusic

  然后进入mongodb查看爬取结果得到响应歌手的歌曲信息:

  

  三、爬虫系列总结

  至此,Scrapy框架已经完成了QQ音乐的爬取,Python网络爬虫数据采集实战系列也结束了。一般来说,爬虫是一项细致的工作,需要掌握固定的套路,努力寻找网络数据的规律。只有线索才能成功爬取,同时也要尽量防止对方服务器负载过大或者自己的输入输出不成比例。完整代码可在头条号私信“QQ音乐”获取。上篇文章涉及的基础知识请参考以下链接:

  爬虫需要知道的基础知识,这一点就够了!Python网络爬虫实战系列

  本文将带你深入了解和学习Python爬虫库!从现在开始,不用担心数据

  Python爬虫有多简单?本文将带你实战豆瓣电影TOP250数据爬取!

  一篇搞懂Python网络爬虫解析库的文章!收录多个示例

  谁说同花顺很难爬?本文带你学习如何使用Python爬取动态金融网页!

  谁说京东产品难爬?一篇文章教你用Python搭建电商网站爬虫!

  Fiddler抓包Python网络爬虫今日头条应用!附代码

  参考链接:

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线