使用python+spark爬取百度热搜写入mysql

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
全局流量管理 GTM,标准版 1个月
简介: 本次算是爬取的第一个demo,百度热搜只是用来测试,写入的mysql也肯定不是最优解,到后期应该会写入到hbase中,spark也大概会换成flink,不过目前还是spark+mysql

建表语句

首先是建表语句,百度热搜一共有热搜,小说,电影等六个主分类,消息种类中保存的就是这些种类的英文名称,也是url的参数,比如其为热搜的时候,对应的地址为https://top.baidu.com/board?tab=realtime,而如果变成小说则会变成https://top.baidu.com/board?tab=novel,tab后面的参数值就代表了其分类的不同。


/

createtable if not exists hot_context(    id int primary key auto_increment comment '自增主键',    key_kind varchar(255) comment '消息种类',    time_send long comment '消息获取时间',    hot_num int comment '消息热度',    value_context text comment '消息缩写',    value_all text comment '消息内容') comment ='百度热搜消息表';

然后消息热度表示爬取消息时,消息的热搜指数;消息缩写和消息内容则是消息的缩略以及简述,不过有部分消息是没有简述的,这里会置为null,下图中邓超情人节……和金莎……其实都是value_context中的内容,14日,孙俪……则为value_all的内容。

导入依赖

importurllib.requestasrequestfromlxmlimportetreeimporttimeimportcalendarfrompyspark.sqlimportSparkSessionfrompyspark.sqlimportRowimportrandomimportlogging

urllib是python中爬取网站的库,其有四个主要模块,这里只使用到了request[打开和读取url]的功能。

然后是lxml,这里使用xpath来解析爬取出来的html数据,写法和正则类似,比如我想爬取div块中class为a的里面的文本数据,可以写为etree.HTML(html数据).xpath('//div[@class,"a"]/text()'),其后的time和calendar则是用来获得当前消息时间戳的。

sparksession用来创建spark会话。

row则是用来封装数据,将爬取到的数据变成row格式,再写入dataframe中。

random是用来从几个UserAgent中选择其中一个,当然如果手头有多个proxies,也可以使用random.choice来选择其中一个。

logging用来打印日志信息。

尝试连接百度热搜

# 尝试连接百度热搜网站defgetBaiduHtml(opener, req_url):
MAX_RETRY=6fortriesinrange(MAX_RETRY):
try:
# 尝试10sweb_txt=opener.open(req_url, timeout=10).read().decode('utf8')
returnweb_txtexceptExceptionase:
logging.warning(str(e) +',html_url:{0}'.format(req_url))
time.sleep(3)
iftries< (MAX_RETRY-1):
continueelse:
print('Has tried {0} times to access url {1}, all failed!'.format(MAX_RETRY, req_url))
returnNone

这一段代码基本是从网上copy的,就是在链接超时后再次尝试,一直尝试够六次,当时在链接的时候,最初采用的代理是http格式的,但是百度热搜是https,所以代理失效,走的本地,后来增加了https的代理,却一直无法使用,以为是网络超时,结果是代理的问题,这段代码就保留了下来没有删除,此处返回的数据为html的源文件数据。

解析百度html数据

defgetBaiduData():
list_res= []
# 百度热搜前缀url_text="https://top.baidu.com/board?tab="# 代理UserAgent=random.choice(
        ['Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.36',
'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36',
'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.0 Safari/537.36'])
headers= {'User-Agent': UserAgent}
# 如果有代理,此处可以设置代理 {'http':'','https':''},为空,则使用的是本地ipproxies= {}
# 百度热搜数组hot_arr= ["realtime", "novel", "movie", "teleplay", "car", "game"]
forhot_textinhot_arr:
req_url=request.Request(url=url_text+hot_text, headers=headers)
# 获得handler对象handler=request.ProxyHandler(proxies=proxies)
# 获得opener对象opener=request.build_opener(handler)
web_txt=getBaiduHtml(opener, req_url)
web_html=etree.HTML(web_txt).xpath('//div[contains(@class,"c-single-text-ellipsis") or ''contains(@class,"hot-desc_1m_jR small_Uvkd3 ") or''contains(@class,"hot-index_1Bl1a")]/text()')
# 中间数据tmp_res=""forhtml_txtinweb_html:
new_html_txt=html_txt.strip()
ifnew_html_txt!=""andnew_html_txt.isdigit():
iftmp_res!="":
list_res.append(Row(tmp_res))
tmp_res=hot_text+"\t"+str(calendar.timegm(time.gmtime())) +"\t"+new_html_txtelifnew_html_txt!=""andnotnew_html_txt.isdigit():
tmp_res=tmp_res+"\t"+new_html_txtelse:
passreturnlist_res

代码中的百度热搜数组对应的就是上面提到的六个热搜类别,这里没有直接采用urlopen来获得数据,不是urlopen无法获得数据,只是想增加一些小难度,先用request.Request返回请求对象,然后用reques.ProxyHandler来获得handler对象,之后获得opener对象,大致说法如下:

  1. 使用相关的 Handler处理器 来创建特定功能的处理器对象;
  2. 然后通过 urllib.request.build_opener()方法使用这些处理器对象,创建自定义opener对象;
  3. 使用自定义的opener对象,调用open()方法发送请求。

此步骤是因为基本的urlopen()方法不支持代理、cookie等其他的HTTP/HTTPS高级功能。

然后根据xpath解析出全文三个不同内容的class,其对应可以在网站自行查看,大致是热搜指数,缩略和简述。

下面的判断逻辑是依据是爬取解析出来的第一个数据是热搜指数,也就是数字,当为数字的时候会将当前热搜分类,时间戳和指数变成以tab键分割的字符串,而不是数字的时候,则会将其他内容追加到后面,当再次出现数字的时候,会将该字符串变成row并写入到一个list集合中,字符串又变成当前热搜分类,时间戳和指数变成以tab键分割的字符串。

主方法

这里没有将写入mysql和df的转化单独抽离出来,一方面是因为难度不大,一方面是因为懒🦥。

if__name__=='__main__':
spark=SparkSession.builder.appName("sql").master("local").getOrCreate()
df=spark.createDataFrame(getBaiduData())
df.createTempView("tmpTable1")
prop= {
'user': 'root',
'password': '',
'driver': 'com.mysql.cj.jdbc.Driver'    }
jdbc_url='jdbc:mysql://localhost:3306/baiduhot'# 格式化row中数据sql_format=spark.sql(
"select split_part(_1,'\\t',1) as key_kind,""split_part(_1,'\\t',2) as time_send,""split_part(_1,'\\t',3) as hot_num,""split_part(_1,'\\t',4) as value_context,""case when length(split_part(_1,'\\t',5))>0 then split_part(_1,'\\t',5) end as value_all ""from tmpTable1"    )
# 写入数据库sql_format.write.jdbc(url=jdbc_url, table='hot_context', mode='append', properties=prop)
print("the success")
spark.stop()

方法内均为spark代码,master设为local,只在idea单独运行,第三行创建的df是解析百度数据后返回的数据,第四行是将该df注册成临时表tmpTable1,prop中是连接mysql需要的信息,没有使用df本身的方法来解析数据,而是采用sql,道理依旧是简单。

最后就是正常用追加的方式将数据写入到表中,需要注意将jdbc的jar包放在spark的jars目录下,否则会报错。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
12天前
|
数据采集 监控 搜索推荐
基于python的百度资讯爬虫的设计与实现
本文介绍了一个基于Python语言的网络爬虫设计与实现,该爬虫利用urllib.request和BeautifulSoup库从百度新闻中抓取新闻标题、链接、内容摘要和来源信息,通过模拟浏览器行为和添加随机等待时间来规避反爬机制,为新闻数据分析和舆情监控提供支持。
|
13天前
|
搜索推荐 前端开发 数据可视化
基于Python协同过滤的旅游景点推荐系统,采用Django框架,MySQL数据存储,Bootstrap前端,echarts可视化实现
本文介绍了一个基于Python协同过滤算法的旅游景点推荐系统,该系统采用Django框架、MySQL数据库、Bootstrap前端和echarts数据可视化技术,旨在为用户提供个性化的旅游推荐服务,提升用户体验和旅游市场增长。
基于Python协同过滤的旅游景点推荐系统,采用Django框架,MySQL数据存储,Bootstrap前端,echarts可视化实现
|
11天前
|
SQL 关系型数据库 MySQL
Python系列:教你使用PyMySQL操作MySQL数据库
Python系列:教你使用PyMySQL操作MySQL数据库
21 8
|
8天前
|
关系型数据库 MySQL 数据库
Python操作Mysql,这一篇就够了
Python操作Mysql,这一篇就够了
15 1
|
12天前
|
数据采集 数据可视化 关系型数据库
【优秀python web设计】基于Python flask的猫眼电影可视化系统,可视化用echart,前端Layui,数据库用MySQL,包括爬虫
本文介绍了一个基于Python Flask框架、MySQL数据库和Layui前端框架的猫眼电影数据采集分析与可视化系统,该系统通过爬虫技术采集电影数据,利用数据分析库进行处理,并使用Echart进行数据的可视化展示,以提供全面、准确的电影市场分析结果。
|
12天前
|
数据采集 存储 自然语言处理
【优秀python案例】基于百度贴吧的数据采集与文本分析设计与实现
本文介绍了百度贴吧数据采集与文本分析的设计与实现,包括自动化采集帖子数据、进行情感分析和主题分析,以及使用可视化技术展示分析结果。
|
13天前
|
前端开发 数据挖掘 关系型数据库
基于Python的哔哩哔哩数据分析系统设计实现过程,技术使用flask、MySQL、echarts,前端使用Layui
本文介绍了一个基于Python的哔哩哔哩数据分析系统,该系统使用Flask框架、MySQL数据库、echarts数据可视化技术和Layui前端框架,旨在提取和分析哔哩哔哩用户行为数据,为平台运营和内容生产提供科学依据。
|
数据安全/隐私保护 数据格式 Python
python爬取快手商品数据
python爬取快手商品数据
|
数据采集 Python
python使用aiohttp通过设置代理爬取基金数据
python使用aiohttp通过设置代理爬取基金数据
|
数据采集 Web App开发 JSON
python爬取共享单车悄然涨价大众的评论数据
python爬取共享单车悄然涨价大众的评论数据