Scrapy框架爬取百度新闻
文章目录
- 一、前期准备
- 二、初识Scrapy
- 三、网页分析(重点&难点)
- 四、代码编写
- 五、结果展示
本次博客使用 Scrapy爬虫框架 爬取 百度新闻,并保存到 Mysql数据库 中。除了知道爬虫知识外,还需要了解一下数据库的知识。
…
如果你不太了解数据库的知识,请你不要慌,看我的Mysql系列博客就好啦…(虽然是转载,但也是我一个字一个字敲的,都是经过大脑和验证的)
一、前期准备
- 会简单使用Fidder进行抓包;
- 会一点Scrapy爬虫框架(网上教程很多,也可看我第二章内容);
- 会一点简单的数据库操作(建库、建表、增删查改)
二、初识Scrapy
工欲善其事必先利其器,Scrapy框架的安装,请看我这篇博客 (传送门), 里面详细且正确的告诉大家如何安装Scrapy框架。
安装好Scrapy框架后,我们该如何使用它呢?下面我会简单介绍几个Scrapy框架常用的命令。知道了这些命令,我们就能创建并运行爬虫项目了。
- startproject命令
- genspider命令
- crawl命令
注意:这些命令都是在cmd中操作,且是以管理员身份打开
1、startproject命令
语法:
scrapy startproject 爬虫项目名
我们可以通过这个命令创建一个Scrapy框架爬虫项目,如下:
说明:
- D:\pythonProgram\scrapytest1路径 是创建存放爬虫项目的文件夹的路径。这个文件夹在何处创建,读者随意;
- scrapy startprojct 是固定搭配,scrapy是Scrapy框架中每个命令必带的前缀;
- newsbaidu 是爬虫项目名
创建完之后,我们可以去此路径查看一下,如下:
2、genspider命令
语法:
scrapy genspider -t 爬虫文件模板 爬虫文件名 域名
我们可以通过这个命令创建一个爬虫文件,注意,是创建爬虫文件。前面那个startprojct命令是创建爬虫项目,一个项目里面可有多个爬虫文件。
在Scrapy框架中,其为我们提供了四个爬虫文件模板,我们可以在cmd中输入 scrapy genspider -l(这里是小写的l,不是数字1),如下:
一般的爬虫项目,我们使用basic模板创建爬虫文件即可,其它3个模板,如需求,请读者自行了解!
创建爬虫文件,如下:
说明:
- cd newsbaidu:创建爬虫文件前,需先进入爬虫项目;
- scrapy genspider -t:是创建爬虫文件模板的固定搭配;
- basic:爬虫文件模板
- news:项目里的爬虫文件名
- baidu.com:要爬取网站的域名
3、crawl命令
语法:
# 显示爬取日志
scrapy crawl 爬虫文件名
或
# 不显示爬取日志
scrapy crawl 爬虫文件名 --nolog
这个命令的作用是运行爬虫文件,进行网页数据爬取。现在还未编写爬虫文件,需等到最后运行爬虫文件时,再演示。
4、简析项目文件结构
从上往下,逐一简单介绍:
- newsbaidu:项目名称
- spiders:爬虫主程序脚本文件夹
- news.py:爬虫脚本文件,数据爬取主要在此
- items.py:指定保存文件的数据结构,即数据的封装实体类
- middlewares.py:中间件,处理request和reponse等相关配置
- pipelines.py:项目管道文件,可对采集后数据的进行处理
- settings.py:设置文件,指定项目的一些配置
- scrapy.cfg:配置文件,指定路径
我们主要操作的文件,就是上面加粗的文件。
三、网页分析(重点&难点)
1、简单分析网页
打开浏览器进入百度新闻首页,如下:
复制 “让城市留在记忆,让人们记住乡愁”,进入首页源代码查看是否存在这句话,如下:
发现有这句话。我们进行第一个猜测:可能全部的新闻标题和新闻url都在首页源代码中。为了验证这个猜测,我们再选择首页中的一句话 “伊朗宣布将于周五开始与中俄军演,为伊斯兰革命后首次”,进入首页源代码查看是否存在,如下:
经过几次上面的操作,我们发现:除了热点要闻可以在首页源代码都查询,其他都不能 。这个时候,我们可能要想一下,百度新闻中其他新闻标题和url信息是不是 通过JS的Ajax异步请求生成的呢 ?下面我们就通过Fiddler抓包分析。
2、Fiddler抓包分析
前面 :我使用的是谷歌浏览器,所以要想用Fidder进行抓包分析,除了下载一个Fiddler软件,还需要给谷歌浏览器安装一个SwitchyOmega插件,怎么在谷歌下载和安装这个插件,请自行百度啦(不然跑题了…)。使用火狐浏览器的朋友呢,不用下载这个插件,可以在浏览器里面直接配置,也请自行百度啦。
(1)打开Fiddler软件
(一个小技巧:在刷新页面之前,Fiddler里面就开始不知道抓些什么包了,我们可以在底下输入:clear,清除掉这些记录哦!)
(2)在谷歌浏览器里面刷新百度新闻页面
刷新完页面后,我们进入Fiddler,它已经为我们抓了很多包了,接下来要靠我们自己了。这里也有小技巧呐:如果我们前面分析出,数据可能存放在JS文件中,我们肯定要特别关照一下下Fiddler抓的JS文件了。请看下图:
这显示的是什么鬼??是人看的吗?! 这当然不是人看的了,我们可以复制里面的Unicode编码,借助Python自带的编辑器IDLE,将其转码,我们人再看。如下:
原来那串Unicode编码是这个意思,真有意思啊。我们复制这句话到百度新闻首页找找,如下:
嘿!还真找到了。我们进行第二个猜测:数据都存放在这个JS文件里面。我们就再去Fiddler里面观察一下这个JS文件,发现好像不太对,这里面的数据一看明显就太少了,和百度新闻首页里面那么多新闻数据完全不是一个数量级别。难道?数据还存放在其他JS文件中?就再去Fiddler里面找其他JS文件…(读者,你先去找吧…任你找,找破天也不会找的,哈哈哈哈哈)
好像找不到了,其他JS文件夹里面没有数据啊…我再重新刷新一下百度新闻页面,说不定会出来。刷啊刷啊,找啊找啊,还是没的。
这个时候,我们好像束手无策。别急,我们百度一下,看以前有没有人分析过百度新闻,看他们怎么找到规律的。百度了一下,好像、貌似没有…(如果有,也请读者好好琢磨琢磨,他们是怎么找到规律的!)
我们就盯着有数据的JS文件看,进行天马行空的想象了。我们观察到JS的url好像有点古怪,如下:
好像,有数据的JS文件的url和底下那几个比较显眼的绿色的get请求文件的url有那么一丢丢的类似。如果英文水平还行,应该可以看懂箭头指向的单词是什么意思。然后,再对比一下百度新闻首页中的新闻类别,我们好像发现了一点什么!!
复制这些文件的url(对着这个文件,右击 > Copy > Just Url),进行对比和测试,如下:
经过对比和测试这些url,我们可以发现:
- 每个url后面的 t=1579xxxxxxx,应该是时间戳,删除也不会对进入url有影响;
- 除了本地新闻的url还多一串:&ajax=json,我们进行测试,这个代表JSON格式,为其他url后面加上这个字符串,也都从html网页格式变成了JSON格式。
有了这些新闻的JSON数据格式,接下来就是分析正则表达式,提取我们想要的数据了。
- 对本地新闻,标题正则表达式:“title”:"(.*?)";url正则表达式:“url”:"(.*?)"
- 对其他新闻,标题正则表达式:“m_title”:"(.*?)";url正则表达式:“m_url”:"(.*?)"
分析,我们就到此结束。如有疑问,请多多练习!
四、代码编写
1、爬虫项目创建(先在cmd中)
2、数据库表的创建
3、爬虫代码编写
(1)进入Pycharm,导入爬虫项目newsbaidu
File > Open >
(2)设置配置文件settings.py
(3)item.py编写
(4)编写news.py
# -*- coding: utf-8 -*-
import scrapy
import re
from scrapy.http import Request
from newsbaidu.items import NewsbaiduItemclass NewsSpider(scrapy.Spider):name = 'news'# 域名allowed_domains = ['baidu.com']# 爬取开始网址start_urls = ['https://news.baidu.com/widget?id=LocalNews&ajax=json']# 百度新闻类别allid = ['LocalNews', 'civilnews', 'InternationalNews', 'EnterNews', 'SportNews', 'FinanceNews', 'TechNews','MilitaryNews', 'InternetNews', 'DiscoveryNews', 'LadyNews', 'HealthNews', 'PicWall']# 构造百度新闻网址allurl = []for url in range(0, len(allid)):thisid = allid[url]thisurl = "https://news.baidu.com/widget?id=" + thisid + "&ajax=json"allurl.append(thisurl)def parse(self, response):for i in range(0, len(self.allurl)):print("第" + str(i) + "个栏目")print("爬取网址:" + self.allurl[i])yield Request(self.allurl[i], callback=self.next)"""某个新闻模块数据爬取"""def next(self, response):print("进入next方法")# 进入本地新闻if (response.url == 'https://news.baidu.com/widget?id=LocalNews&ajax=json'):data = response.body.decode("utf-8", "ignore")alldata = self.get_data(data, self.pattern(1))else: # 进入其他新闻data = response.body.decode("utf-8", "ignore")alldata = self.get_data(data, self.pattern(2))# 创建BaidunewsItem对象item = NewsbaiduItem()item["title"] = alldata[0]item["link"] = alldata[1]yield item# 用于正则表达式的匹配def pattern(self, choice):# 存放正则表达式pattern = []if (choice == 1):# 编写正则表达式pat1 = '"title":"(.*?)"'pat2 = '"url":"(.*?)"'pattern.append(pat1)pattern.append(pat2)elif (choice == 2):# 编写正则表达式pat1 = '"m_title":"(.*?)"'pat2 = '"m_url":"(.*?)"'pattern.append(pat1)pattern.append(pat2)return pattern'''处理本地新闻数据,获取新闻标题和url'''def get_data(self, data, pattern):print("调用了get_data1方法")# 编写正则表达式pat1 = pattern[0]pat2 = pattern[1]# 爬取网页数据里面的新闻标题titledata = re.compile(pat1, re.S).findall(data)# 爬取网页数据里面的url数据urldata = re.compile(pat2, re.S).findall(data)# 存放新闻标题titilall = []# 存放新闻urlurlall = []for i in range(0, len(titledata)):# 转码,显示成中文——这步只是为了调试方便thistitle = re.sub(r'(\\u[\s\S]{4})', lambda x: x.group(1).encode("utf-8").decode("unicode-escape"),titledata[i])titilall.append(thistitle)# 处理url,用/替换\/for j in range(0, len(urldata)):thisurl = re.sub("\\\/", "/", urldata[j])urlall.append(thisurl)# 存放新闻标题和urlalldata = []alldata.append(titilall)alldata.append(urlall)return self.deal_data(alldata)# 处理新闻标题和新闻url,使其一一对应def deal_data(self, alldata):print("进入deal_data方法")# 判断新闻标题和url是否一一对应if (len(alldata[0]) == len(alldata[1])):return alldataelse: # 根据源码分析,我们可以得知:都是新闻标题比url多,我们只要从前删除标题直到标题数量与url数量相等时即可# 首先求出新闻标题比新闻url多几个count_url = len(alldata[0]) - len(alldata[1])for i in range(0, count_url):alldata[0].pop(0)return alldata
5、编写pipelines.py
把数据出入数据库中。
# -*- coding: utf-8 -*-
import pymysql
# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://docs.scrapy.org/en/latest/topics/item-pipeline.htmlclass NewsbaiduPipeline(object):def process_item(self, item, spider):# 连接数据库conn = pymysql.connect(host="localhost",user="root",passwd="ydjws",db="test",port=3306,charset="utf8",)# 游标cur = conn.cursor()for i in range(0, len(item["title"])):title = item["title"][i]link = item["link"][i]# 编写sql语句sql = "insert into t_news(title,link) values ('" + title + "','" + link + "')"try:cur.execute(sql)conn.commit()except Exception as err:print(err)conn.rollback()conn.close()return item
五、结果展示
1、执行scrapy crawl news --nolog
2、查看数据库
Scrapy框架爬取百度新闻相关推荐
- 【python 爬虫】 scrapy 入门--爬取百度新闻排行榜
scrapy 入门–爬取百度新闻排行榜 环境要求:python2/3(anaconda)scrapy库 开发环境:sublime text + windows cmd 下载scrapy(需要pytho ...
- scrapy获取a标签的连接_python爬虫——基于scrapy框架爬取网易新闻内容
python爬虫--基于scrapy框架爬取网易新闻内容 1.需求[前期准备] 2.分析及代码实现(1)获取五大板块详情页url(2)解析每个板块(3)解析每个模块里的标题中详情页信息 点击此处,获取 ...
- 19. python爬虫——基于scrapy框架爬取网易新闻内容
python爬虫--基于scrapy框架爬取网易新闻内容 1.需求 [前期准备] 2.分析及代码实现 (1)获取五大板块详情页url (2)解析每个板块 (3)解析每个模块里的标题中详情页信息 1.需 ...
- 利用scrapy框架爬取网易新闻排行榜
wyxw.py中代码 # -*- coding: utf-8 -*- import scrapy from ..items import WyxwItemclass WyxwSpider(scrapy ...
- python爬百度新闻_13、web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息...
crapy爬取百度新闻,爬取Ajax动态生成的信息,抓取百度新闻首页的新闻rul地址 有多网站,当你浏览器访问时看到的信息,在html源文件里却找不到,由得信息还是滚动条滚动到对应的位置后才显示信息, ...
- scrapy框架爬取虎扑论坛球队新闻
目录 Scrapy 框架 制作 Scrapy 爬虫 一共需要4步: Scrapy的安装介绍 Windows 安装方式 一. 新建项目(scrapy startproject) 二.明确目标(mySpi ...
- Python网络爬虫数据采集实战:Scrapy框架爬取QQ音乐存入MongoDB
通过前七章的学习,相信大家对整个爬虫有了一个比较全貌的了解 ,其中分别涉及四个案例:静态网页爬取.动态Ajax网页爬取.Selenium浏览器模拟爬取和Fillder今日头条app爬取,基本 ...
- Python网络爬虫数据采集实战(八):Scrapy框架爬取QQ音乐存入MongoDB
通过前七章的学习,相信大家对整个爬虫有了一个比较全貌的了解 ,其中分别涉及四个案例:静态网页爬取.动态Ajax网页爬取.Selenium浏览器模拟爬取和Fillder今日头条app爬取,基本涵盖了爬虫 ...
- scrapy框架 爬取重庆工程学院
scrapy框架 爬取重庆工程学院 目的:爬取重庆工程学院 中的管理学院的学院动态 百度搜索重庆工程学院,看到如图所示 因为我使用scarpy框架,不知道如何创建项目的,可以看看我之前的文章(简单的理 ...
- 利用python的scrapy框架爬取google搜索结果页面内容
scrapy google search 实验目的 爬虫实习的项目1,利用python的scrapy框架爬取google搜索结果页面内容. https://github.com/1012598167/ ...
最新文章
- 权限表管理之保存权限表数据
- 技术12期:如何设计rowkey使hbase更快更好用【大数据-全解析】
- github开源推荐:SuperSocket, 可扩展的 Socket 服务器框架
- Windows 键盘操作快捷方式积累
- 如使用JDBC连接Mysql数据库
- java redis的应用_Redis-Java 交互的应用
- CGVAE -> Delinker -> DeepCoy
- OpenCV-Canny边缘检测
- 【干货】前端单元测试入门
- 软件需求工程 高校教学平台 项目总体计划
- 2022年2月份报告合集(共326份)
- 飞行控制PID算法——无人机飞控
- 深度可分离卷积及其代码实现
- 小程序中从后台获取内容纯数字、纯字母超出父盒子宽度时不换行 解决方法
- python三国演义人物出现次数_Python分析《三国演义》人物出场次数,孔明第二,赵云第五...
- win7 按修改时间范围文件搜索
- 如何划分测试集和训练集
- PetShop的系统架构设计(转Bruce Zhang(wayfarer) )
- 计算机能直接识别的算法表示形式,几种常用的图像置乱算法:图像识别算法
- e-dialog出现额外多了一层遮罩