一、常见的Python爬虫库
1. Requests:处理Http请求。
2. lxml:HTML和XML文件解。
3. BeautifulSoup:网络抓取框架,用于解析和提取HTML和XML数据,通常用于小数据量的处理,不支持异步操作,通常搭配lxml使用。
4. Scrapy:比较强大的爬虫框架,适用于复杂大型任务的爬取。
5. Selenium:模拟用户访问浏览器操作,适合处理JS渲染的网页。
6. re:正则表达式。
二、爬虫示例 1
示例描述: 爬取自己的csdn博客,统计每篇博客的访问量,制作一个柱状图,以访问量从大到小的方式显示。
1. 从“个人主页”爬取所有所有文章的链接
1.1 查看爬取规则
打开个人主页,右键->检查:可以看到每篇文章的链接挂在哪个标签的哪个属性下( <article>标签下的<a>标签中的href属性值即为每篇文章的链接 )
1.2 提取网页中的所有文章ip
from bs4 import BeautifulSoup #pip3 install beautifulsoup4
from urllib.request import urlopen
homePage_url="https://blog.csdn.net/beautiful77moon?spm=1010.2135.3001.5421" #你的csdn个人主页链接
homePage_html=urlopen(homePage_url).read().decode('utf-8')
soup=BeautifulSoup(homePage_html,features='lxml')
#1.查找所有的<article>标签
li_articles=soup.find_all('article')
#2.取出所有<article>标签下<a>中的href属性值
article_urls=[]
for item in li_articles:
link=item.find_all('a')
article_urls.append(link[0]['href'])
print(link[0]['href'])
当页面内容过多时,需要下拉”加载”,才能显示所有内容,所以需要一个工具模拟浏览器行为,自动滚动页面以加载更多内容。urllib无法处理这种情况,所以一般不建议使用 urllib。
1.3 使用selenium模拟浏览器。
1.3.1 下载浏览器驱动(以Edge为例)
1. 查看自己的浏览器版本(点击浏览器右上角的三个点->设置->关于 Microsoft Edge)
2. 下载对应版本的驱动:Microsoft Edge WebDriver | Microsoft Edge Developer
3. 解压到一个目录下(这个目录后续会用到)
1.3.2 下载关键的依赖包
1. 浏览器模拟器selenium:pip install selenium –index-url https://pypi.tuna.tsinghua.edu.cn/simple
2. 处理网页的beautifulsoup:pip install beautifulsoup4 –index-url https://pypi.tuna.tsinghua.edu.cn/simple
1.3.3 代码
1. 模拟浏览器,实现“滑动鼠标”下拉页面以加载更多数据的行为
2. 从个人主页提取所有文章的url并打印
from selenium import webdriver
from selenium.webdriver.edge.service import Service
from selenium.webdriver.edge.options import Options
from bs4 import BeautifulSoup
import time
# 设置 Edge驱动 的路径
edge_driver_path = 'E:SoftWare_workdownloadedgedriver_win64msedgedriver.exe' # 替换为你本地的 EdgeDriver 路径
# 配置 Edge浏览器选项
edge_options = Options()
edge_options.add_argument("--headless") # # 无头模式。不可视化浏览器页面。如果注释掉这行,每次运行代码都会打开浏览器页面。
# 启动浏览器
service = Service(edge_driver_path)
driver = webdriver.Chrome(service=service, options=edge_options)
# 打开网页
homePage_url = "https://blog.csdn.net/beautiful77moon?spm=1010.2135.3001.5421"
driver.get(homePage_url)
# 滚动页面以加载更多内容
# driver.execute_script("return window.pageYOffset + window.innerHeight") 用于获取当前视口底部相较于页面顶部位置的 JavaScript 代码
# window.pageYOffset:当前视口顶部相对于页面顶部的垂直滚动距离。表示页面的顶部已经滚动了多少像素 假设为1200px
# window.innerHeight:浏览器视口的高度(即当前显示区域的高度) 假设为800px
# last_height = window.pageYOffset + window.innerHeight = 2000px
last_height = driver.execute_script("return window.pageYOffset + window.innerHeight")
while True:
#driver.execute_script("window.scrollTo(0, document.body.scrollHeight);") #使用 JavaScript 滚动到页面底部以加载更多数据
#模拟鼠标滚动
#第一个参数表示水平方向不滚动
#第二个参数表示垂直方向上滚动1000像素
driver.execute_script(f"window.scrollBy(0, 1000);")
time.sleep(5) #等待页面加载
new_height = driver.execute_script("return window.pageYOffset + window.innerHeight")#driver.execute_script("return document.body.scrollHeight") #获取当前页面的高度,检测是否已加载更多内容
if new_height == last_height:
break
last_height = new_height
# 获取页面源代码
page_source = driver.page_source
# 关闭浏览器
driver.quit()
# 解析页面内容
soup = BeautifulSoup(page_source, 'lxml')
# 查找所有的<article>标签
li_articles = soup.find_all('article')
# 取出所有<article>标签下<a>中的href属性值
article_urls = []
for item in li_articles:
links = item.find_all('a')
if links:
article_urls.append(links[0].get('href'))
print(links[0].get('href'))
print(len(article_urls)) #116
2. 统计每篇文章的访问量
2.1 查看爬取规则
参考 1.1
2.2 爬取数据
注意:1.3.3 代码中的 driver.quit() 需要注释掉,否则不能正常浏览其他网页,会报错
import re
#分析每篇文章的访问量,收藏量,点赞数
class Article_Detail:
def __init__(self,article_name="",read="",collect="",like=""):
self.article_name=article_name #文章名字
self.read=read #阅读量
self.collect=collect #收藏量
self.like=like #点赞量
articles_details=[]
for item in article_urls:
driver.get(item)
page_source=driver.page_source
#driver.quit()
soup = BeautifulSoup(page_source,'lxml')
# 阅读量、收藏量、点赞数所在标签过滤
bar_content=Article_Detail()
get_name=(soup.find('h1',attrs='title-article',id='articleContentId')).get_text()
get_read=(soup.find('span','read-count')).get_text(strip=True) #strip=True去除前后空格
get_collection=(soup.find('span','get-collection')).get_text(strip=True)
get_like=(soup.find('span',id='blog-digg-num')).get_text(strip=True)
#统计文章的阅读量、收藏量、点赞数
bar_content.article_name=get_name
match=re.search(r'd+',get_read) #使用正则表达式匹配字符串中的一个或多个数字
bar_content.read= match.group() if match else 0
match = re.search(r'd+', get_collection) # 使用正则表达式匹配字符串中的一个或多个数字
bar_content.collect = match.group() if match else 0
match = re.search(r'd+', get_like) # 使用正则表达式匹配字符串中的一个或多个数字
bar_content.like = match.group() if match else 0
articles_details.append(bar_content)
for item in articles_details:
print(item.article_name+":阅读量["+item.read+"],收藏量["+item.collect+"],点赞数["+item.like+"]")
运行结果:
三、爬虫框架Scrapy
使用Scrapy框架优化示例1中的代码,并将爬取的信息进行保存。
1. Scrapy框架与BeautifulSoup框架的区别:
Scrapy教程
[功能方面]
- Scrapy:
- 数据类型:可以处理各种类型的数据。
- 功能方面:包括请求管理、数据解析/提取、数据存储(JSON、CSV、XML)等。
- 请求方式:使用异步 I/O,使其能够高效地处理大量请求。
- 支持的特性:支持中间件、管道、爬虫调度等功能,适合大规模的抓取项目。
- 自动处理:能够自动处理重定向、用户代理、更换IP等。
- BeautifulSoup:
- 数据类型:是一个用于解析 HTML 和 XML 的库,主要用于提取网页内容。
- 功能方面:只解析和提取数据,不包括请求管理和数据存储。
- 请求方式:同步I/O操作,通常与requests等库配合使用。
[性能方面]
- Scrapy:
- 性能高:因其异步I/O和内置的请求调度功能,适合大规模抓取。
- 扩展性强:可以通过中间件和扩展进行功能扩展,如处理JavaScript渲染内容等。
- BeautifulSoup:
- 性能较低:通常用于小规模数据抓取,不支持异步操作。
- 扩展性有限,主要集中与数据解析,需要与其他工具组合使用。
[适用场景]
- Scrapy:
- 大规模爬取:适合需要高效处理大量数据的项目。
- 复杂任务抓取:适用于抓取并处理多个页面、分页、异步请求等复杂任务。
- BeautifulSoup:
- 小型抓取:适合简单的数据提取任务。
- 数据解析:已经知道了html内容,只需要解析和提取数据时。
2. 代码
未完结
四、使用Jupyter对结果进行可视化
未完结