热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

【爬虫实战案例1】基于BeautifulSoup+Re+Pandas简单实现爬虫需求

前言分享一篇使用部分爬虫技术简单实现对媒体类网页按需求爬取文章并保存到本地指定文件夹的案例,仅供相关学习者参考,学习过程切勿对网站频繁访问而造成网页瘫

前言 

分享一篇使用部分爬虫技术简单实现对媒体类网页按需求爬取文章并保存到本地指定文件夹的案例,仅供相关学习者参考,学习过程切勿对网站频繁访问而造成网页瘫痪,量力而为!!!

BeautifulSoup的简单使用:https://inganxu.blog.csdn.net/article/details/122783587




爬取需求

爬取地址:建筑档案-建筑行业全产业链内容共建平台

爬取涉及技术:Requests(访问)、BeautifulSoup、Re(解析)、Pandas(保存)

爬取目的:仅用于练习巩固爬虫技术

爬取目标:


  1. 将网页首页中每个文章的标题、作者、发布时间、文章链接保存到指定位置的excel文件中,excel名称为data
  2. 将每个文章的文本保存到指定位置的文档中,并以文章标题命名
  3. 将每个文章的图片保存到指定位置的文件夹中,并以文章标题 + 图片序号命名



爬取思路

发起首页网页请求,获取响应内容

解析首页网页数据,获取文章的标题、作者、发布时间、文章链接信息

汇总网站首页信息,保存到excel

        发起文章网页请求,获取响应内容

        解析文章网页数据,获取文章的文本图片链接信息

        保存文章内容到指定文档

                发起图片网页请求,获取响应内容

                保存图片到指定文件夹




代码讲解

下面以爬虫思路的顺序讲解每个步骤的实现方式以及注意事项


步骤一:导入相关库

import requests # 用于发起网页请求,返回响应内容
import pandas as pd # 生成二维数据,保存到excel中
import os # 文件保存
import time # 减慢爬虫速度
import re # 提取解析内容
from bs4 import BeautifulSoup # 对响应内容解析数据

没有相关的库就自行安装

win键+r,调出CMD窗口,输入以下代码

pip install 欠缺的库名



步骤二:设置防识别爬虫措施

"""
记录爬虫时间
设置访问网页基础信息
"""
start_time = time.time()
start_url = "https://www.jzda001.com"
header = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36'}

hearder:表头,自己复制浏览器的表头,实在不会找就直接复制我的用




步骤三:主页访问,解析响应内容

response = requests.get(url=start_url, headers=header) # 发起请求
html = response.text # 提取响应内容
soup = BeautifulSoup(html, 'lxml') # 解析响应内容
content = soup.find_all('div', attrs={'class': 'content-left'})[0] # 筛选并提取仅需爬虫的内容# 使用列表来装载爬虫信息
item = {}
href_list = []
title_list = []
author_list = []
releasetime_list = []# 获取文章链接
for href in content.find_all('a', href=re.compile('^/index/index/details')):if href['href'] not in href_list:href_list.append(href['href'])# 获取文章标题
for title in content.find_all('p', class_=re.compile('(twoline|sub oneline|oneline)'))[:-1]:title_list.append(title.text)# 获取文章作者和发布时间
for author_time in content.find_all(&#39;p&#39;, attrs&#61;{&#39;class&#39;: &#39;name&#39;}):if len(author_list) <20:author &#61; re.findall(r&#39;(?<&#61;\s)\D&#43;(?&#61;\s\.)&#39;, author_time.text)[0]author_list.append(author.replace(&#39; &#39;, &#39;&#39;))if len(releasetime_list) <20:time &#61; re.findall(r&#39;\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}&#39;, author_time.text)releasetime_list.append(time[0])

解析过程发现获取的内容头部或尾部有不需要的信息&#xff0c;因此使用列表切片方式将元素剔除掉




步骤四&#xff1a;数据清洗

# 主页面数据清洗
author_clear &#61; []
for i in author_list:if i !&#61; &#39;.&#39;:author_clear.append(i.replace(&#39;\n&#39;, &#39;&#39;).replace(&#39; &#39;, &#39;&#39;))
author_list &#61; author_clear
time_clear &#61; []
for j in releasetime_list:time_clear.append(j.replace(&#39;\n&#39;, &#39;&#39;).replace(&#39; &#39;, &#39;&#39;).replace(&#39;:&#39;, &#39;&#39;))
releasetime_list &#61; time_clear
title_clear &#61; []
for n in title_list:title_clear.append(n.replace(&#39;&#xff1a;&#39;, &#39; &#39;).replace(&#39;&#xff01;&#39;, &#39; &#39;).replace(&#39;|&#39;, &#39; &#39;).replace(&#39;/&#39;, &#39; &#39;).replace(&#39; &#39;, &#39; &#39;))
title_list &#61; title_clear

查看网页结构&#xff0c;可以看到标题、作者、发布时间都有一些系统敏感字符&#xff08;影响后续无法创建文件夹&#xff09;

所以&#xff0c;需要把解析到的数据作数据清洗后才能使用 




步骤五&#xff1a;访问文章链接并解析提取响应内容

通过对比网页结构的&#64;href属性链接和文章的真实链接&#xff0c;可知解析到的url需要拼接网址首页进去

 


# 访问文章并保存文本信息和图片到指定文件夹
for nums in range(20):text_list &#61; []img_url_list &#61; []article_url &#61; start_url &#43; href_list[nums]response_url &#61; requests.get(article_url, headers&#61;header, timeout&#61;1)html_text &#61; response_url.textsoup_article &#61; BeautifulSoup(html_text, &#39;lxml&#39;)# 获取子页面文本&#xff08;用find_all方法&#xff09;content_article &#61; soup_article.find_all(&#39;div&#39;, attrs&#61;{&#39;class&#39;: &#39;content&#39;})[-1]text &#61; &#39;&#39;for i in content_article:text &#61; text &#43; i.texttext_list.append(text)# 获取子页面图片链接&#xff08;用select方法&#xff09;soup_article_url &#61; content_article.select(&#39;.pgc-img > img&#39;)for url in soup_article_url:img_url_list.append(url[&#39;src&#39;])

拼接文本内容是因为获取到的文本信息是一段一段分开的&#xff0c;需要拼接在一起&#xff0c;才是完整的文章文本信息




步骤六&#xff1a;创建多层文件夹

新建多层文件夹file_name &#61; "建筑档案爬虫文件夹" # 文件夹名称path &#61; r&#39;d:/&#39; &#43; file_nameurl_path_file &#61; path &#43; &#39;/&#39; &#43; title_list[nums] &#43; &#39;/&#39; # 拼接文件夹地址if not os.path.exists(url_path_file):os.makedirs(url_path_file)

因为创建的文件夹是&#xff1a;“./爬虫文件夹名称/文章标题名称/”&#xff0c;所以需要用os.makedirs来创建多层文件夹

注意文件名称最后带 “/”




步骤七&#xff1a;保存子页面图片

当建立好文件夹后&#xff0c;就开始访问每个文章的图片链接&#xff0c;并且保存下来

# 保存子页面图片for index, img_url in enumerate(img_url_list):img_rep &#61; requests.get(img_url, headers&#61;header, timeout&#61;5) # 设置超时时间index &#43;&#61; 1 # 每保存图片一次&#xff0c;显示数量&#43;1img_name &#61; title_list[nums] &#43; &#39; 图片&#39; &#43; &#39;{}&#39;.format(index) # 图片名称img_path &#61; url_path_file &#43; img_name &#43; &#39;.png&#39; # 图片地址with open(img_path, &#39;wb&#39;) as f:f.write(img_rep.content) # 以二进制的方式写入f.close()



步骤八&#xff1a;保存子页面文本

先保存文本再保存图片也可以&#xff0c;需要注意两者的写入方式

# 保存网页文本txt_name &#61; str(title_list[nums] &#43; &#39; &#39; &#43; author_list[nums] &#43; &#39; &#39; &#43; releasetime_list[nums]) # 文本名称txt_path &#61; url_path_file &#43; &#39;/&#39; &#43; txt_name &#43; &#39;.txt&#39; # 文本地址with open(txt_path, &#39;w&#39;, encoding&#61;&#39;utf-8&#39;) as f:f.write(str(text_list[0]))f.close()



步骤九&#xff1a;文章信息汇总

将网站首页的所有文章标题、作者、发布时间、文章链接都保存到一个excel文件夹中

# 主页面信息保存
data &#61; pd.DataFrame({&#39;title&#39;: title_list,&#39;author&#39;: author_list,&#39;time&#39;: releasetime_list,&#39;url&#39;: href_list})
data.to_excel(&#39;{}./data.xls&#39;.format(path), index&#61;False)



完整代码&#xff08;面向过程版&#xff09;

# &#xff01;/usr/bin/python3.9
# -*- coding:utf-8 -*-
# &#64;author:inganxu
# CSDN:inganxu.blog.csdn.net
# &#64;Date:2022年2月3日import requests # 用于发起网页请求&#xff0c;返回响应内容
import pandas as pd # 生成二维数据&#xff0c;保存到excel中
import os # 文件保存
import time # 减慢爬虫速度
import re # 提取解析内容
from bs4 import BeautifulSoup # 对响应内容解析数据start_time &#61; time.time()start_url &#61; "https://www.jzda001.com"
header &#61; {&#39;user-agent&#39;: &#39;Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36&#39;}response &#61; requests.get(url&#61;start_url, headers&#61;header) # 发起请求
html &#61; response.text # 提取响应内容
soup &#61; BeautifulSoup(html, &#39;lxml&#39;) # 解析响应内容
content &#61; soup.find_all(&#39;div&#39;, attrs&#61;{&#39;class&#39;: &#39;content-left&#39;})[0] # 筛选并提取仅需爬虫的内容# 使用列表来装载爬虫信息
item &#61; {}
href_list &#61; []
title_list &#61; []
author_list &#61; []
releasetime_list &#61; []# 获取文章链接
for href in content.find_all(&#39;a&#39;, href&#61;re.compile(&#39;^/index/index/details&#39;)):if href[&#39;href&#39;] not in href_list:href_list.append(href[&#39;href&#39;])# 获取文章标题
for title in content.find_all(&#39;p&#39;, class_&#61;re.compile(&#39;(twoline|sub oneline|oneline)&#39;))[:-1]:title_list.append(title.text)# 获取文章作者和发布时间
for author_time in content.find_all(&#39;p&#39;, attrs&#61;{&#39;class&#39;: &#39;name&#39;}):if len(author_list) <20:author &#61; re.findall(r&#39;(?<&#61;\s)\D&#43;(?&#61;\s\.)&#39;, author_time.text)[0]author_list.append(author.replace(&#39; &#39;, &#39;&#39;))if len(releasetime_list) <20:time &#61; re.findall(r&#39;\d{4}-\d{1,2}-\d{1,2}\s\d{1,2}:\d{1,2}:\d{1,2}&#39;, author_time.text)releasetime_list.append(time[0])# 主页面数据清洗
author_clear &#61; []
for i in author_list:if i !&#61; &#39;.&#39;:author_clear.append(i.replace(&#39;\n&#39;, &#39;&#39;).replace(&#39; &#39;, &#39;&#39;))
author_list &#61; author_clear
time_clear &#61; []
for j in releasetime_list:time_clear.append(j.replace(&#39;\n&#39;, &#39;&#39;).replace(&#39; &#39;, &#39;&#39;).replace(&#39;:&#39;, &#39;&#39;))
releasetime_list &#61; time_clear
title_clear &#61; []
for n in title_list:title_clear.append(n.replace(&#39;&#xff1a;&#39;, &#39; &#39;).replace(&#39;&#xff01;&#39;, &#39; &#39;).replace(&#39;|&#39;, &#39; &#39;).replace(&#39;/&#39;, &#39; &#39;).replace(&#39; &#39;, &#39; &#39;))
title_list &#61; title_clear# 访问文章并保存文本信息和图片到指定文件夹
for nums in range(20):text_list &#61; []img_url_list &#61; []article_url &#61; start_url &#43; href_list[nums]response_url &#61; requests.get(article_url, headers&#61;header, timeout&#61;1)html_text &#61; response_url.textsoup_article &#61; BeautifulSoup(html_text, &#39;lxml&#39;)print("正在爬取第{}个页面&#xff01;&#xff01;&#xff01;".format(nums &#43; 1))# 获取子页面文本&#xff08;用find_all方法&#xff09;content_article &#61; soup_article.find_all(&#39;div&#39;, attrs&#61;{&#39;class&#39;: &#39;content&#39;})[-1]text &#61; &#39;&#39;for i in content_article:text &#61; text &#43; i.texttext_list.append(text)# 获取子页面图片链接&#xff08;用select方法&#xff09;soup_article_url &#61; content_article.select(&#39;.pgc-img > img&#39;)for url in soup_article_url:img_url_list.append(url[&#39;src&#39;])# 新建多层文件夹file_name &#61; "建筑档案爬虫文件夹" # 文件夹名称path &#61; r&#39;d:/&#39; &#43; file_nameurl_path_file &#61; path &#43; &#39;/&#39; &#43; title_list[nums] &#43; &#39;/&#39; # 拼接文件夹地址if not os.path.exists(url_path_file):os.makedirs(url_path_file)# 保存子页面图片for index, img_url in enumerate(img_url_list):img_rep &#61; requests.get(img_url, headers&#61;header, timeout&#61;5) # 设置超时时间index &#43;&#61; 1 # 每保存图片一次&#xff0c;显示数量&#43;1img_name &#61; title_list[nums] &#43; &#39; 图片&#39; &#43; &#39;{}&#39;.format(index) # 图片名称img_path &#61; url_path_file &#43; img_name &#43; &#39;.png&#39; # 图片地址with open(img_path, &#39;wb&#39;) as f:f.write(img_rep.content) # 以二进制的方式写入f.close()print(&#39;第{}张图片保存成功&#xff0c;保存地址为&#xff1a;&#39;.format(index), img_path)# 保存网页文本txt_name &#61; str(title_list[nums] &#43; &#39; &#39; &#43; author_list[nums] &#43; &#39; &#39; &#43; releasetime_list[nums]) # 文本名称txt_path &#61; url_path_file &#43; &#39;/&#39; &#43; txt_name &#43; &#39;.txt&#39; # 文本地址with open(txt_path, &#39;w&#39;, encoding&#61;&#39;utf-8&#39;) as f:f.write(str(text_list[0]))f.close()print("该页面文本保存成功,文本地址为&#xff1a;", txt_path)print("爬取成功&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;")print(&#39;\n&#39;)# 主页面信息保存
data &#61; pd.DataFrame({&#39;title&#39;: title_list,&#39;author&#39;: author_list,&#39;time&#39;: releasetime_list,&#39;url&#39;: href_list})
data.to_excel(&#39;{}./data.xls&#39;.format(path), index&#61;False)
print(&#39;保存成功,excel文件地址&#xff1a;&#39;, &#39;{}/data.xls&#39;.format(path))print(&#39;爬取完成!!!!&#39;)
end_time &#61; time.time()
print(&#39;爬取所用时长&#xff1a;&#39;, end_time - start_time)



结语

后续有时间再对该案例扩展防反爬措施&#xff08;ip池、表头池、响应访问&#xff09;、数据处理&#xff08;数据分析、数据可视化&#xff09;等内容




参考文章

【爬虫实战案例1】基于Requests&#43;Xpath&#43;Pandas简单实现爬虫需求_inganxu-CSDN博客

【爬虫实战案例1】基于Scrapy&#43;Xpath简单实现爬虫需求_inganxu-CSDN博客_scrapy爬虫案例


推荐阅读
  • 本文介绍了使用 Python 编程语言高效抓取微博文本和动态网页图像数据的方法。通过详细的示例代码,展示了如何利用爬虫技术获取微博内容和动态图片,为数据采集和分析提供了实用的技术支持。对于对网络数据抓取感兴趣的读者,本文具有较高的参考价值。 ... [详细]
  • 在今天的实践中,我深入学习了网页图像抓取技术,通过编写爬虫程序批量获取网站上的图片资源。具体来说,我选择了一个包含大量高质量图片的网站作为练习对象,并成功实现了将这些图片批量下载到本地存储。这一过程不仅提升了我对爬虫技术的理解,还增强了我的编程能力。 ... [详细]
  • 如何将Python与Excel高效结合:常用操作技巧解析
    本文深入探讨了如何将Python与Excel高效结合,涵盖了一系列实用的操作技巧。文章内容详尽,步骤清晰,注重细节处理,旨在帮助读者掌握Python与Excel之间的无缝对接方法,提升数据处理效率。 ... [详细]
  • 服务器部署中的安全策略实践与优化
    服务器部署中的安全策略实践与优化 ... [详细]
  • 利用爬虫技术抓取数据,结合Fiddler与Postman在Chrome中的应用优化提交流程
    本文探讨了如何利用爬虫技术抓取目标网站的数据,并结合Fiddler和Postman工具在Chrome浏览器中的应用,优化数据提交流程。通过详细的抓包分析和模拟提交,有效提升了数据抓取的效率和准确性。此外,文章还介绍了如何使用这些工具进行调试和优化,为开发者提供了实用的操作指南。 ... [详细]
  • 在PHP中实现腾讯云接口签名,以完成人脸核身功能的对接与签名配置时,需要注意将文档中的POST请求改为GET请求。具体步骤包括:使用你的`secretKey`生成签名字符串`$srcStr`,格式为`GET faceid.tencentcloudapi.com?`,确保参数正确拼接,避免因请求方法错误导致的签名问题。此外,还需关注API的其他参数要求,确保请求的完整性和安全性。 ... [详细]
  • 在使用 `requests` 库进行 HTTP 请求时,如果遇到 `requests.exceptions.SSLError: HTTPSConnectionPool` 错误,通常是因为 SSL 证书验证失败。解决这一问题的方法包括:检查目标网站的 SSL 证书是否有效、更新本地的 CA 证书库、禁用 SSL 验证(不推荐用于生产环境)或使用自定义的 SSL 上下文。此外,确保 `requests` 库和相关依赖项已更新到最新版本,以避免潜在的安全漏洞。 ... [详细]
  • 利用树莓派畅享落网电台音乐体验
    最近重新拾起了闲置已久的树莓派,这台小巧的开发板已经沉寂了半年多。上个月闲暇时间较多,我决定将其重新启用。恰逢落网电台进行了改版,回忆起之前在树莓派论坛上看到有人用它来播放豆瓣音乐,便萌生了同样的想法。通过一番调试,终于实现了在树莓派上流畅播放落网电台音乐的功能,带来了全新的音乐享受体验。 ... [详细]
  • 本文介绍了如何利用Struts1框架构建一个简易的四则运算计算器。通过采用DispatchAction来处理不同类型的计算请求,并使用动态Form来优化开发流程,确保代码的简洁性和可维护性。同时,系统提供了用户友好的错误提示,以增强用户体验。 ... [详细]
  • 使用 ListView 浏览安卓系统中的回收站文件 ... [详细]
  • 优化后的标题:深入探讨网关安全:将微服务升级为OAuth2资源服务器的最佳实践
    本文深入探讨了如何将微服务升级为OAuth2资源服务器,以订单服务为例,详细介绍了在POM文件中添加 `spring-cloud-starter-oauth2` 依赖,并配置Spring Security以实现对微服务的保护。通过这一过程,不仅增强了系统的安全性,还提高了资源访问的可控性和灵活性。文章还讨论了最佳实践,包括如何配置OAuth2客户端和资源服务器,以及如何处理常见的安全问题和错误。 ... [详细]
  • 深入探索HTTP协议的学习与实践
    在初次访问某个网站时,由于本地没有缓存,服务器会返回一个200状态码的响应,并在响应头中设置Etag和Last-Modified等缓存控制字段。这些字段用于后续请求时验证资源是否已更新,从而提高页面加载速度和减少带宽消耗。本文将深入探讨HTTP缓存机制及其在实际应用中的优化策略,帮助读者更好地理解和运用HTTP协议。 ... [详细]
  • 本文深入探讨了HTTP头部中的Expires与Cache-Control字段及其缓存机制。Cache-Control字段主要用于控制HTTP缓存行为,其在HTTP/1.1中得到了广泛应用,而HTTP/1.0中主要使用Pragma:no-cache来实现类似功能。Expires字段则定义了资源的过期时间,帮助浏览器决定是否从缓存中读取资源。文章详细解析了这两个字段的具体用法、相互关系以及在不同场景下的应用效果,为开发者提供了全面的缓存管理指南。 ... [详细]
  • 七款高效编辑器与笔记工具推荐:KindEditor自动换行功能解析
    本文推荐了七款高效的编辑器与笔记工具,并详细解析了KindEditor的自动换行功能。其中,轻笔记QingBiJi是一款完全免费的记事本软件,用户可以通过其简洁的界面和强大的功能轻松记录和管理日常事务。此外,该软件还支持多平台同步,确保用户在不同设备间无缝切换。 ... [详细]
  • 本项目在Java Maven框架下,利用POI库实现了Excel数据的高效导入与导出功能。通过优化数据处理流程,提升了数据操作的性能和稳定性。项目已发布至GitHub,当前最新版本为0.0.5。该项目不仅适用于小型应用,也可扩展用于大型企业级系统,提供了灵活的数据管理解决方案。GitHub地址:https://github.com/83945105/holygrail,Maven坐标:`com.github.83945105:holygrail:0.0.5`。 ... [详细]
author-avatar
哭着说再见0
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有