零基础爬虫入门(六) 您所在的位置:网站首页 百度百科数据爬取 零基础爬虫入门(六)

零基础爬虫入门(六)

2023-09-12 09:12| 来源: 网络整理| 查看: 265

  大家好,我是不温卜火,是一名计算机学院大数据专业大三的学生,昵称来源于成语—不温不火,本意是希望自己性情温和。作为一名互联网行业的小白,博主写博客一方面是为了记录自己的学习过程,另一方面是总结自己所犯的错误希望能够帮助到很多和自己一样处于起步阶段的萌新。但由于水平有限,博客中难免会有一些错误出现,有纰漏之处恳请各位大佬不吝赐教!暂时只在csdn这一个平台进行更新,博客主页:https://buwenbuhuo.blog.csdn.net/。

PS:由于现在越来越多的人未经本人同意直接爬取博主本人文章,博主在此特别声明:未经本人允许,禁止转载!!!

目录 一、需求分析1.1、爬什么1、 网站 1.2、存哪里1、本地磁盘文件2、数据库3、数据仓库 1.3、怎么爬1.4、怎么抽1.5、怎么存 二、详细设计2.1、怎么爬2.2、怎么抽2.3、怎么存 三、案例代码3.1、抽取url3.2、获取新的url1、深度优先爬取2、 广度优先爬取 3.3 去重1、使用set()方法进行URL去重和层数控制2、使用bloom_filter去重 四、example(此部分只是思路,完整代码在3.3的第2部分)4.1、可以控制格式的爬虫4.2、可以控制层数的深度优先爬虫1. 代码2. 运行结果

1

一个爬虫程序的开发顺序如下图: 2

一、需求分析 1.1、爬什么 1、 网站

如果我们要爬取网站,在此我们以百度百科为例:

1. 如果我们想要查看网络爬虫词条开始的三层节点,首先我们需要了解网页结构 3 2. 如果我们想要找到词条名称、URL、描述、关键字信息等数据,那么我们需要了解数据存放位置 4 5 1.2、存哪里

关于数据存储到哪里?其实学长我的个人感受是要具体情况集体分析,视具体情况而定。因为可选太多了。当然了在确定存储之前,我们还是要先确定存放位置、文件类型的。常见的存储如下:

1、本地磁盘文件 如果只是存储到本地的话,我们常使用的有txt、csv格式等。 2、数据库 1. 关系型数据1.Mysql 我们比较常用的是mysql,至于为什么常用大家心知肚明,开源免费。当然了它能存储的数据量与吞吐量有限。 62.SQLServer3.Oracle 2. 非关系型数据库1.MongoDB2.redis3.hbase 3、数据仓库 hive 1.3、怎么爬

网站我们在此选择的为百度百科,至于为什么选择百度百科来作为案例!是因为百度百科比较稳定。

爬取策略 无更新(百度知识比较稳定) or 深度/广度优先 1.4、怎么抽

数据 比如说要抽取description、keyword、summary这些数据

方法 先使用字符串截取,因为现在还没有使用到正则表达式

1.5、怎么存

我们先把文件当成数据的存储载体

二、详细设计 2.1、怎么爬 选一个python库作为主力库无更新(百度百科较稳定) =>即爬即弃深度/广度优先=>数据结构设计URL去重=>逻辑设计、方法选择 2.2、怎么抽 字符串截取=>str自带方法正则表达式=>设计正则表达式Python库抽取=>bs4 2.3、怎么存

文件单存或者批量存法

三、案例代码 3.1、抽取url

引入urllib包和re包后,首先请求对网站进行访问,然后分析网页源代码,并使用正则表达式编写信息抽取规则,使用findall方法将所有正则表达式所匹配的信息抽取出来。

代码如下 import urllib.request as ur import re r = ur.urlopen("https://baike.baidu.com/item/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB") # 对百度百科关键词条为网络爬虫的URL的进行访问 content = r.read().decode('utf-8') href = re.compile(r'href=[\'"]?(/item[^\'" >]+)') # 利用正则表达式将网页中所需的链接表达出来 new_urls=href.findall(content) # 使用findall方法将所有链接信息抽取出来 print(new_urls) # 打印该网页中的所有链接 运行结果 7 可能有些同学不知道URL中的乱码是什么意思。 学长在此再次重申一遍,此部分为URL编码,我们通过解码可以看到其解码后即为我们的关键词网络爬虫。如下图 8 在线解码工具(点击蓝色字体):站长工具 3.2、获取新的url

经历了上一步的爬取后,我们获取了当前网页的所有链接的URL。但是我们是否可以对所爬取的链接再进行进一步的爬取呢?下面我们尝试对网页进行深度优先爬取。 在获得了第一层网页的链接信息后,对URL进行拼接,并不断得对新获取URL进行爬取

1、深度优先爬取 1. 源码 count = 0 r = re.compile(r'href=[\'"]?(/item[^\'" >]+)') # 抽取所需链接信息的正则语言规则 seed = "/item/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB" # 这是网络爬虫词条 stack = [seed] # 设置种子链接的栈(使用列表模拟栈) storage = {} while count ]+)') # 抽取所需链接信息的正则语言规则 seed = "/item/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB" # 这是网络爬虫词条 queue = [seed] # 设置种子链接的队列(使用列表模拟队列) storage = {} while count ]+)') seed = '/item/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB' # 这是网络爬虫词条 queue = [[seed]] for i in range(floors): # 限制爬取范围在设定的层数范围内 queue.append([]) storage = {} used = set() # 设置集合存放爬取过的url while len(queue[0])>0 or count!=0: # 种子队列不为空或者层数不为零 try: url = queue[count].pop(-1) print(url+" "+str(count)) # 打印当前链接和层数 html = ur.urlopen('https://baike.baidu.com'+url).read().decode('utf-8') storage[url]=html used.add(url) # 将爬取过的URL放入集合中 new_urls = r.findall(html) if count } used = set() while len(queue[0])>0 or count!=0: try: url = queue[count].pop(-1) print(url+" "+str(count)) html = ur.urlopen('https://baike.baidu.com'+url).read().decode('utf-8') new_urls = r.findall(html) storage[ur.unquote(url[6:])]=getinfo(html,set(new_urls)) # 使用unquote解码,并调用getinfo函数将格式化后的数据存入字典中 if count ]+)') seed = "/item/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB" # 这是网络爬虫词条 queue = [seed] # 设置种子链接的队列(使用列表模拟队列) storage = {} # 初始化实现层数控制:实际上在到达控制层数之前都是执行深度优先,在控制层需要宽度优先 while len(queue) > 0: try: url = queue.pop(-1) # 取出队列最后一条URL html = ur.urlopen("https://baike.baidu.com" + url).read().decode('utf-8') # 对URL进行拼接 print(html) new_urls = r.findall(html) # 提取当前网页下的所有链接URL信息 queue.extend(new_urls) storage[url] = len(new_urls) except Exception as e: print(url) print(e)

14

4.2、可以控制层数的深度优先爬虫 1. 代码 import urllib.request as ur import re #初始化参数 count = 0 # 控制层数 floors = 2 # 在程序开始时可以设定需要爬取的层数 # 初始化数据存储结构 r = re.compile(r'href=[\'"]?(/item[^\'" >]+)') seed = "/item/%E7%BD%91%E7%BB%9C%E7%88%AC%E8%99%AB" # 这是网络爬虫词条 queue = [[seed]] # 设置种子链接的队列(使用列表模拟队列) # 初始化实现层数控制:实际上在到达控制层数之前都是执行深度优先,在控制层需要宽度优先 # 嵌套list在不去改变爬虫的深度优先的策略基础上,保证队列处于一个堆栈的状态 for i in range(floors): queue.append([]) # 使用嵌套list存放不同层的数据 storage = {} # 字典型,用于保存数据 used = set() # 集合,自带去重的特性 while len(queue[0])>0 or count!=0: # 所有层数爬取完毕+列表中没有url时结束 try: # 取出队列最后一条URL url = queue[count].pop(-1) print(url+" "+str(count)) html = ur.urlopen('https://baike.baidu.com'+url).read().decode('utf-8') # 对URL进行拼接 storage[url] = html used.add(url) new_urls = r.findall(html) # 提取当前网页下的所有链接URL信息 # 在没有达到控制层前,页面引入的URL都会被加入到该层的list中,完成深度优先 if count


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有