来源
在互联网充满数据、而数据又被称作“新石油”的时代,网页抓取在各类应用中变得尤为重要且实用。网页抓取是指从网站中提取或“抓取”信息的过程。网页抓取有时也被称为网络采集或网页数据提取。从网站上复制文本并粘贴到本地系统,也是网页抓取的一种形式,但这是手动操作。通常,网页抓取指借助网络爬虫自动提取数据。网络爬虫是使用 HTTP 协议连接万维网的脚本,使您能够以自动化方式获取数据。
无论您是数据科学家、工程师,还是任何需要分析大量数据集的人,具备从网页抓取数据的能力都是一项实用技能。假设您在网上找到了数据,但没有直接的下载方式,那么使用 Python 进行网页抓取就能把数据提取成可用的格式,随后导入并以多种方式使用。
网页抓取的一些实际应用包括:
收集具备特定技能的候选人简历,
提取带有特定标签的 Twitter 推文,
市场营销中的线索生成,
从亚马逊等电商网站抓取商品详情和评论——本教程的重点
除了上述用例,网页抓取还广泛用于自然语言处理,从网站提取文本以训练深度学习模型。
在继续之前,请注意,像亚马逊这类网站可能会更新其特定服务条款,或新增技术限制,从而影响其内容的访问与再利用方式。您有责任查看该网站的服务条款 和robots.txt 文件,确保您的具体用例符合要求。政策可能变更,许可也可能有所不同。
网页抓取的潜在挑战
因此,为应对上述挑战,有多种可行方案。一种是采用持续集成与持续交付(CI/CD)以及持续维护,因为网站的改动具有动态性。
另一种更现实的做法是使用各网站与平台提供的应用程序接口(API)。例如,Facebook 和 Twitter 为想要使用其数据或提取信息的开发者提供了专门的 API,比如获取所有好友与共同好友并绘制关系图。通过 API 获取的数据格式不同于常规网页抓取,即 JSON 或 XML;而在标准网页抓取中,您主要处理 HTML 格式的数据。
什么是 Beautiful Soup?
Beautiful Soup 是一个纯 Python 库,用于从网站中提取结构化数据。它允许您解析 HTML 和 XML 文件中的数据。它充当辅助模块,以类似且更优的方式与 HTML 交互,就像您使用其他开发者工具与网页交互一样。
它通常能为程序员节省数小时甚至数天的工作,因为它可以与您喜欢的解析器(如 lxml 和 html5lib)配合,为遍历、搜索和修改解析树提供更“Pythonic”的方式。
Beautiful Soup 的另一项强大而实用的功能是能将抓取到的文档智能地转换为 Unicode,并将输出文档转换为 UTF-8。作为开发者,除非文档本身未指定编码或 Beautiful Soup 无法检测到编码,否则您无需为此操心。
与其他常见的解析或抓取技术相比,它的速度也被认为更快。
解析器类型
来源
如需进一步了解,请参见这里 。
理论够多了,对吧?现在就安装 Beautiful Soup,并用 Python 开始学习它的功能与能力。
第一步,您需要通过终端或 Jupyter Lab 安装 Beautiful Soup 库。安装 Beautiful Soup 的最佳方式是使用 pip,请确保已安装 pip 模块。
!pip3 install beautifulsoup4
技术支持
Requirement already satisfied: beautifulsoup4 in / usr/ local/ lib/ python3. 7 / site- packages ( 4.7 .1 )
Requirement already satisfied: soupsieve>= 1.2 in / usr/ local/ lib/ python3. 7 / site- packages ( from beautifulsoup4) ( 1.9 .5 )
技术支持
导入必要的库
接下来导入抓取网站数据所需的包,并使用 seaborn、matplotlib 和 bokeh 对数据进行可视化。
import pandas as pd
import numpy as np
import matplotlib. pyplot as plt
import seaborn as sns
% matplotlib inline
import re
import time
from datetime import datetime
import matplotlib. dates as mdates
import matplotlib. ticker as ticker
from urllib. request import urlopen
from bs4 import BeautifulSoup
import requests
技术支持
抓取亚马逊畅销书
您将要抓取的 URL 如下:https://www.amazon.in/gp/bestsellers/books/ 。页面参数可调整以访问每一页的数据。因此,若要访问所有页面,您需要循环遍历所有页面以获取所需数据集,但首先需要从网站找出总页数。
要连接到 URL 并获取 HTML 内容,需要完成以下事项:
定义一个 get_data 函数,传入页码作为参数,
定义一个 user-agent,帮助绕过被识别为抓取器的检测,
将 URL 传给 requests.get 并传入 user-agent 头作为参数,
从 requests.get 中提取内容,
抓取指定页面并赋给 soup 变量,
接下来且非常重要的一步是确定承载所需全部数据的父标签。您将要提取的数据包括:
下图显示了父标签的位置,当您将鼠标悬停其上时,所有所需元素都会被高亮显示。
与父标签类似,您需要找到书名、作者、评分、评分人数和价格等属性。前往您想要抓取的网页,选中该属性,右键选择“检查元素”。这将帮助您在纯 HTML 网页中定位需要提取的具体信息字段,如下图所示:
请注意,有些作者名称未在亚马逊注册,因此需要对这些作者额外进行 find。在下面的代码单元中,您会看到针对作者名称的嵌套 if-else 条件,用以提取作者/出版方名称。
no_pages = 2
def get_data ( pageNo) :
headers = { "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:66.0) Gecko/20100101 Firefox/66.0" , "Accept-Encoding" : "gzip, deflate" , "Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" , "DNT" : "1" , "Connection" : "close" , "Upgrade-Insecure-Requests" : "1" }
r = requests. get( 'https://www.amazon.in/gp/bestsellers/books/ref=zg_bs_pg_' + str ( pageNo) + '?ie=UTF8&pg=' + str ( pageNo) , headers= headers)
content = r. content
soup = BeautifulSoup( content)
alls = [ ]
for d in soup. findAll( 'div' , attrs= { 'class' : 'a-section a-spacing-none aok-relative' } ) :
name = d. find( 'span' , attrs= { 'class' : 'zg-text-center-align' } )
n = name. find_all( 'img' , alt= True )
author = d. find( 'a' , attrs= { 'class' : 'a-size-small a-link-child' } )
rating = d. find( 'span' , attrs= { 'class' : 'a-icon-alt' } )
users_rated = d. find( 'a' , attrs= { 'class' : 'a-size-small a-link-normal' } )
price = d. find( 'span' , attrs= { 'class' : 'p13n-sc-price' } )
all1= [ ]
if name is not None :
all1. append( n[ 0 ] [ 'alt' ] )
else :
all1. append( "unknown-product" )
if author is not None :
all1. append( author. text)
elif author is None :
author = d. find( 'span' , attrs= { 'class' : 'a-size-small a-color-base' } )
if author is not None :
all1. append( author. text)
else :
all1. append( '0' )
if rating is not None :
all1. append( rating. text)
else :
all1. append( '-1' )
if users_rated is not None :
all1. append( users_rated. text)
else :
all1. append( '0' )
if price is not None :
all1. append( price. text)
else :
all1. append( '0' )
alls. append( all1)
return alls
技术支持
下面的代码单元将执行以下功能:
在 for 循环中调用 get_data 函数,
for 循环从 1 迭代到 页数+1。
由于输出为嵌套列表,您需要先将列表展平,然后传入 DataFrame。
最后,将数据框保存为 CSV 文件。
results = [ ]
for i in range ( 1 , no_pages+ 1 ) :
results. append( get_data( i) )
flatten = lambda l: [ item for sublist in l for item in sublist]
df = pd. DataFrame( flatten( results) , columns= [ 'Book Name' , 'Author' , 'Rating' , 'Customers_Rated' , 'Price' ] )
df. to_csv( 'amazon_products.csv' , index= False , encoding= 'utf-8' )
技术支持
读取 CSV 文件
现在加载您在上一个单元中创建并保存的 CSV 文件。这一步是可选的;您也可以直接使用数据框 df,忽略以下步骤。
df = pd. read_csv( "amazon_products.csv" )
技术支持
df. shape
技术支持
( 100 , 5 )
技术支持
数据框的形状显示,您的 CSV 文件包含 100 行、5 列。
我们来打印数据集的前 5 行。
df. head( 61 )
技术支持
Book Name Author Rating Customers_Rated Price 0 The Power of your Subconscious Mind Joseph Murphy 4.5 out of 5 stars 13,948 ₹ 99.00 1 Think and Grow Rich Napoleon Hill 4.5 out of 5 stars 16,670 ₹ 99.00 2 Word Power Made Easy Norman Lewis 4.4 out of 5 stars 10,708 ₹ 130.00 3 Mathematics for Class 12 (Set of 2 Vol.) Exami... R.D. Sharma 4.5 out of 5 stars 18 ₹ 930.00 4 The Girl in Room 105 Chetan Bhagat 4.3 out of 5 stars 5,162 ₹ 149.00 ... ... ... ... ... ... 56 COMBO PACK OF Guide To JAIIB Legal Aspects Pri... MEC MILLAN 4.5 out of 5 stars 114 ₹ 1,400.00 57 Wren & Martin High School English Grammar and ... Rao N 4.4 out of 5 stars 1,613 ₹ 400.00 58 Objective General Knowledge Sanjiv Kumar 4.2 out of 5 stars 742 ₹ 254.00 59 The Rudest Book Ever Shwetabh Gangwar 4.6 out of 5 stars 1,177 ₹ 194.00 60 Sita: Warrior of Mithila (Ram Chandra Series -... Amish Tripathi 4.4 out of 5 stars 3,110 ₹ 248.00
61 行 × 5 列
我们来对 Ratings、Customers_Rated 和 Price 列做一些预处理。
已知评分满分为 5,只保留评分数值,去掉其余部分。
在 customers_rated 列中,去掉逗号。
在 price 列中,去掉卢比符号与逗号,并按点号分割。
最后将这三列转换为整数或浮点数。
df[ 'Rating' ] = df[ 'Rating' ] . apply ( lambda x: x. split( ) [ 0 ] )
技术支持
df[ 'Rating' ] = pd. to_numeric( df[ 'Rating' ] )
技术支持
df[ "Price" ] = df[ "Price" ] . str . replace( '₹' , '' )
技术支持
df[ "Price" ] = df[ "Price" ] . str . replace( ',' , '' )
技术支持
df[ 'Price' ] = df[ 'Price' ] . apply ( lambda x: x. split( '.' ) [ 0 ] )
技术支持
df[ 'Price' ] = df[ 'Price' ] . astype( int )
技术支持
df[ "Customers_Rated" ] = df[ "Customers_Rated" ] . str . replace( ',' , '' )
技术支持
df[ 'Customers_Rated' ] = pd. to_numeric( df[ 'Customers_Rated' ] , errors= 'ignore' )
技术支持
df. head( )
技术支持
Book Name Author Rating Customers_Rated Price 0 The Power of your Subconscious Mind Joseph Murphy 4.5 13948 99 1 Think and Grow Rich Napoleon Hill 4.5 16670 99 2 Word Power Made Easy Norman Lewis 4.4 10708 130 3 Mathematics for Class 12 (Set of 2 Vol.) Exami... R.D. Sharma 4.5 18 930 4 The Girl in Room 105 Chetan Bhagat 4.3 5162 149
我们来验证 DataFrame 的数据类型。
df. dtypes
技术支持
Book Name object
Author object
Rating float64
Customers_Rated int64
Price int64
dtype : object
技术支持
将 DataFrame 中的零值替换为 NaN。
df. replace( str ( 0 ) , np. nan, inplace= True )
df. replace( 0 , np. nan, inplace= True )
技术支持
统计 DataFrame 中 NaN 的数量
count_nan = len ( df) - df. count( )
技术支持
count_nan
技术支持
Book Name 0
Author 6
Rating 0
Customers_Rated 0
Price 1
dtype : int64
技术支持
从上述输出可以看到,共有 6 本书没有作者名,而 1 本书未关联价格。对于想要售书的作者而言,这些信息至关重要,不应忽视填写。
我们将这些 NaN 删除。
df = df. dropna( )
技术支持
作者在亚马逊上的最高定价图书
我们来看看哪些作者的书定价最高。您将可视化前 20 位作者的结果。
data = df. sort_values( [ "Price" ] , axis= 0 , ascending= False ) [ : 15 ]
技术支持
data
技术支持
Book Name Author Rating Customers_Rated Price 56 COMBO PACK OF Guide To JAIIB Legal Aspects Pri... MEC MILLAN 4.5 114 1400.0 98 Diseases of Ear, Nose and Throat P L Dhingra 4.7 118 1285.0 3 Mathematics for Class 12 (Set of 2 Vol.) Exami... R.D. Sharma 4.5 18 930.0 96 Madhymik Bhautik Vigyan -12 (Part 1-2) (NCERT ... Kumar-Mittal 5.0 1 765.0 6 My First Library: Boxset of 10 Board Books for... Wonder House Books 4.5 3116 750.0 38 Indian Polity - For Civil Services and Other S... M. Laxmikanth 4.6 1210 700.0 42 A Modern Approach to Verbal & Non-Verbal Reaso... R.S. Aggarwal 4.4 1822 675.0 27 The Intelligent Investor (English) Paperback –... Benjamin Graham 4.4 6201 650.0 99 Law of CONTRACT & Specific Relief Dr. Avtar Singh 4.4 23 643.0 49 All In One ENGLISH CORE CBSE Class 12 2019-20 Arihant Experts 4.4 493 599.0 72 The Secret Rhonda Byrne 4.5 11220 556.0 86 How to Prepare for Quantitative Aptitude for t... Arun Sharma 4.4 847 537.0 8 Quantitative Aptitude for Competitive Examinat... R S Aggarwal 4.4 4553 435.0 16 Sapiens: A Brief History of Humankind Yuval Noah Harari 4.6 14985 434.0 84 Concept of Physics Part-2 (2019-2020 Session) ... H.C. Verma 4.6 1807 433.0
from bokeh. models import ColumnDataSource
from bokeh. transform import dodge
import math
from bokeh. io import curdoc
curdoc( ) . clear( )
from bokeh. io import push_notebook, show, output_notebook
from bokeh. layouts import row
from bokeh. plotting import figure
from bokeh. transform import factor_cmap
from bokeh. models import Legend
output_notebook( )
技术支持
Loading BokehJS ...
p = figure( x_range= data. iloc[ : , 1 ] , plot_width= 800 , plot_height= 550 , title= "Authors Highest Priced Book" , toolbar_location= None , tools= "" )
p. vbar( x= data. iloc[ : , 1 ] , top= data. iloc[ : , 4 ] , width= 0.9 )
p. xgrid. grid_line_color = None
p. y_range. start = 0
p. xaxis. major_label_orientation = math. pi/ 2
技术支持
show( p)
技术支持
从上图可见,最高定价的两本书分别来自作者 Mecmillan 和 P L Dhingra。
作者的高评分图书
我们来找出哪些作者拥有最高评分的图书,以及这些作者哪些书评分最高。不过,在筛选时,我们会过滤掉评分人数少于 1000 的作者。
data = df[ df[ 'Customers_Rated' ] > 1000 ]
技术支持
data = data. sort_values( [ 'Rating' ] , axis= 0 , ascending= False ) [ : 15 ]
技术支持
data
技术支持
Book Name Author Rating Customers_Rated Price 26 Inner Engineering: A Yogi’s Guide to Joy Sadhguru 4.7 4091 254.0 70 Bhagavad-Gita (Hindi) A. C. Bhaktivedanta 4.7 1023 150.0 11 The Alchemist Paulo Coelho 4.7 22182 264.0 47 Harry Potter and the Philosopher's Stone J.K. Rowling 4.7 7737 234.0 84 Concept of Physics Part-2 (2019-2020 Session) ... H.C. Verma 4.6 1807 433.0 16 Sapiens: A Brief History of Humankind Yuval Noah Harari 4.6 14985 434.0 38 Indian Polity - For Civil Services and Other S... M. Laxmikanth 4.6 1210 700.0 29 Wings of Fire: An Autobiography of Abdul Kalam Arun Tiwari 4.6 3513 301.0 39 The Theory of Everything Stephen Hawking 4.6 2004 199.0 25 The Immortals of Meluha (Shiva Trilogy) Amish 4.6 4538 248.0 23 Life's Amazing Secrets: How to Find Balance an... Gaur Gopal Das 4.6 3422 213.0 34 Dear Stranger, I Know How You Feel Ashish Bagrecha 4.6 1130 167.0 17 The Monk Who Sold His Ferrari Robin Sharma 4.6 5877 137.0 13 How to Win Friends and Influence People Dale Carnegie 4.6 15377 99.0 59 The Rudest Book Ever Shwetabh Gangwar 4.6 1177 194.0
p = figure( x_range= data. iloc[ : , 0 ] , plot_width= 800 , plot_height= 600 , title= "Top Rated Books with more than 1000 Customers Rating" , toolbar_location= None , tools= "" )
p. vbar( x= data. iloc[ : , 0 ] , top= data. iloc[ : , 2 ] , width= 0.9 )
p. xgrid. grid_line_color = None
p. y_range. start = 0
p. xaxis. major_label_orientation = math. pi/ 2
技术支持
show( p)
技术支持
从上述结果可见,评分人数超过 1000 的最高评分前三本书是 Inner Engineering: A Yogi’s Guide to Joy、Bhagavad-Gita (Hindi) 和 The Alchemist。
p = figure( x_range= data. iloc[ : , 1 ] , plot_width= 800 , plot_height= 600 , title= "Top Rated Books with more than 1000 Customers Rating" , toolbar_location= None , tools= "" )
p. vbar( x= data. iloc[ : , 1 ] , top= data. iloc[ : , 2 ] , width= 0.9 )
p. xgrid. grid_line_color = None
p. y_range. start = 0
p. xaxis. major_label_orientation = math. pi/ 2
技术支持
show( p)
技术支持
上图按降序显示了评分人数超过 1000 且评分最高的前 10 位作者,分别是 Sadhguru、A. C. Bhaktivedanta 和 Paulo Coelho。
评分人数最多的作者与图书
虽然我们已经看过最高评分的图书和作者,但基于为该书打分的客户数量来评估最佳作者与图书会更具说服力与可信度。
那么,我们就快速找出来。
data = df. sort_values( [ "Customers_Rated" ] , axis= 0 , ascending= False ) [ : 20 ]
技术支持
data
技术支持
Book Name Author Rating Customers_Rated Price 11 The Alchemist Paulo Coelho 4.7 22182 264.0 1 Think and Grow Rich Napoleon Hill 4.5 16670 99.0 13 How to Win Friends and Influence People Dale Carnegie 4.6 15377 99.0 16 Sapiens: A Brief History of Humankind Yuval Noah Harari 4.6 14985 434.0 18 Rich Dad Poor Dad : What The Rich Teach Their ... Robert T. Kiyosaki 4.5 14591 296.0 10 The Subtle Art of Not Giving a F*ck Mark Manson 4.4 14418 365.0 0 The Power of your Subconscious Mind Joseph Murphy 4.5 13948 99.0 48 The Power of Your Subconscious Mind Joseph Murphy 4.5 13948 99.0 72 The Secret Rhonda Byrne 4.5 11220 556.0 41 1984 George Orwell 4.5 10829 95.0 2 Word Power Made Easy Norman Lewis 4.4 10708 130.0 46 Man's Search For Meaning: The classic tribute ... Viktor E Frankl 4.4 8544 245.0 67 The 7 Habits of Highly Effective People R. Stephen Covey 4.3 8229 397.0 47 Harry Potter and the Philosopher's Stone J.K. Rowling 4.7 7737 234.0 40 One Indian Girl Chetan Bhagat 3.8 7128 113.0 65 Thinking, Fast and Slow (Penguin Press Non-Fic... Daniel Kahneman 4.4 7087 410.0 27 The Intelligent Investor (English) Paperback –... Benjamin Graham 4.4 6201 650.0 17 The Monk Who Sold His Ferrari Robin Sharma 4.6 5877 137.0 53 Ram - Scion of Ikshvaku (Ram Chandra) Amish Tripathi 4.2 5766 262.0 93 The Richest Man in Babylon George S. Clason 4.5 5694 129.0
from bokeh. transform import factor_cmap
from bokeh. models import Legend
from bokeh. palettes import Dark2_5 as palette
import itertools
from bokeh. palettes import d3
colors = itertools. cycle( palette)
palette = d3[ 'Category20' ] [ 20 ]
技术支持
index_cmap = factor_cmap( 'Author' , palette= palette,
factors= data[ "Author" ] )
技术支持
p = figure( plot_width= 700 , plot_height= 700 , title = "Top Authors: Rating vs. Customers Rated" )
p. scatter( 'Rating' , 'Customers_Rated' , source= data, fill_alpha= 0.6 , fill_color= index_cmap, size= 20 , legend= 'Author' )
p. xaxis. axis_label = 'RATING'
p. yaxis. axis_label = 'CUSTOMERS RATED'
p. legend. location = 'top_left'
技术支持
BokehDeprecationWarning : 'legend' keyword is deprecated, use explicit 'legend_label' , 'legend_field' , or 'legend_group' keywords instead
技术支持
show( p)
技术支持
上图是作者的评分与评分人数的散点图。结合该图,可以得出以下结论。
毫无疑问,Paulo Coelho 的《The Alchemist》是最畅销的书,因为评分与评分人数都非常匹配。
作者 Amish Tripathi 的《Ram - Scion of Ikshvaku (Ram Chandra)》评分为 4.2,评分人数 5766;而作者 George S. Clason 的《The Richest Man in Babylon》评分人数相近,但总体评分为 4.5。因此可以认为,更多读者对《The Richest Man in Babylon》给出了较高评分。
结语
恭喜您完成本教程。
本教程介绍了如何使用 Beautiful Soup 抓取亚马逊的数据,以及如何借助 bokeh 绘图库对提取信息进行可视化以获取洞见。想继续深入学习使用 Beautiful Soup 进行网页抓取 的一个不错练习,是去抓取其他网站的数据,看看能从中获得哪些见解。如果您想获取更多关于抓取热门网站的指导,我们还有一篇关于抓取 Reddit 的教程 。
如果您刚开始学习 Python 并希望了解更多内容,欢迎学习 DataCamp 的Python 数据科学入门 课程。
在互联网充满数据、而数据又被称作“新石油”的时代,网页抓取在各类应用中变得尤为重要且实用。网页抓取是指从网站中提取或“抓取”信息的过程。网页抓取有时也被称为网络采集或网页数据提取。从网站上复制文本并粘贴到本地系统,也是网页抓取的一种形式,但这是手动操作。通常,网页抓取指借助网络爬虫自动提取数据。网络爬虫是使用 HTTP 协议连接万维网的脚本,使您能够以自动化方式获取数据。
无论您是数据科学家、工程师,还是任何需要分析大量数据集的人,具备从网页抓取数据的能力都是一项实用技能。假设您在网上找到了数据,但没有直接的下载方式,那么使用 Python 进行网页抓取就能把数据提取成可用的格式,随后导入并以多种方式使用。
网页抓取的一些实际应用包括:
除了上述用例,网页抓取还广泛用于自然语言处理,从网站提取文本以训练深度学习模型。
在继续之前,请注意,像亚马逊这类网站可能会更新其特定服务条款,或新增技术限制,从而影响其内容的访问与再利用方式。您有责任查看该网站的服务条款和robots.txt 文件,确保您的具体用例符合要求。政策可能变更,许可也可能有所不同。
网页抓取的潜在挑战
抓取网站信息时,您会遇到的挑战之一是各网站结构各不相同。也就是说,网站模板千差万别、各具特色;因此在不同网站之间做通用化处理可能会很有难度。
另一项挑战是长期可用性。由于网页开发者会不断更新网站,您无法长期依赖同一个爬虫。即使修改很小,也可能在获取数据时带来阻碍。
因此,为应对上述挑战,有多种可行方案。一种是采用持续集成与持续交付(CI/CD)以及持续维护,因为网站的改动具有动态性。
另一种更现实的做法是使用各网站与平台提供的应用程序接口(API)。例如,Facebook 和 Twitter 为想要使用其数据或提取信息的开发者提供了专门的 API,比如获取所有好友与共同好友并绘制关系图。通过 API 获取的数据格式不同于常规网页抓取,即 JSON 或 XML;而在标准网页抓取中,您主要处理 HTML 格式的数据。
什么是 Beautiful Soup?
Beautiful Soup 是一个纯 Python 库,用于从网站中提取结构化数据。它允许您解析 HTML 和 XML 文件中的数据。它充当辅助模块,以类似且更优的方式与 HTML 交互,就像您使用其他开发者工具与网页交互一样。
它通常能为程序员节省数小时甚至数天的工作,因为它可以与您喜欢的解析器(如
lxml和html5lib)配合,为遍历、搜索和修改解析树提供更“Pythonic”的方式。Beautiful Soup 的另一项强大而实用的功能是能将抓取到的文档智能地转换为 Unicode,并将输出文档转换为 UTF-8。作为开发者,除非文档本身未指定编码或 Beautiful Soup 无法检测到编码,否则您无需为此操心。
与其他常见的解析或抓取技术相比,它的速度也被认为更快。
解析器类型
如需进一步了解,请参见这里。
理论够多了,对吧?现在就安装 Beautiful Soup,并用 Python 开始学习它的功能与能力。
第一步,您需要通过终端或 Jupyter Lab 安装 Beautiful Soup 库。安装 Beautiful Soup 的最佳方式是使用
pip,请确保已安装pip模块。导入必要的库
接下来导入抓取网站数据所需的包,并使用 seaborn、matplotlib 和 bokeh 对数据进行可视化。
抓取亚马逊畅销书
您将要抓取的 URL 如下:https://www.amazon.in/gp/bestsellers/books/。页面参数可调整以访问每一页的数据。因此,若要访问所有页面,您需要循环遍历所有页面以获取所需数据集,但首先需要从网站找出总页数。
要连接到 URL 并获取 HTML 内容,需要完成以下事项:
get_data函数,传入页码作为参数,user-agent,帮助绕过被识别为抓取器的检测,requests.get并传入 user-agent 头作为参数,接下来且非常重要的一步是确定承载所需全部数据的
父标签。您将要提取的数据包括:下图显示了父标签的位置,当您将鼠标悬停其上时,所有所需元素都会被高亮显示。
与父标签类似,您需要找到书名、作者、评分、评分人数和价格等属性。前往您想要抓取的网页,选中该属性,右键选择“检查元素”。这将帮助您在纯 HTML 网页中定位需要提取的具体信息字段,如下图所示:
请注意,有些作者名称未在亚马逊注册,因此需要对这些作者额外进行
find。在下面的代码单元中,您会看到针对作者名称的嵌套 if-else 条件,用以提取作者/出版方名称。下面的代码单元将执行以下功能:
get_data函数,for循环从 1 迭代到 页数+1。读取 CSV 文件
现在加载您在上一个单元中创建并保存的 CSV 文件。这一步是可选的;您也可以直接使用数据框
df,忽略以下步骤。数据框的形状显示,您的 CSV 文件包含 100 行、5 列。
我们来打印数据集的前 5 行。
61 行 × 5 列
我们来对
Ratings、Customers_Rated和Price列做一些预处理。我们来验证 DataFrame 的数据类型。
将 DataFrame 中的零值替换为 NaN。
统计 DataFrame 中 NaN 的数量
从上述输出可以看到,共有 6 本书没有作者名,而 1 本书未关联价格。对于想要售书的作者而言,这些信息至关重要,不应忽视填写。
我们将这些 NaN 删除。
作者在亚马逊上的最高定价图书
我们来看看哪些作者的书定价最高。您将可视化前 20 位作者的结果。
从上图可见,最高定价的两本书分别来自作者
Mecmillan和P L Dhingra。作者的高评分图书
我们来找出哪些作者拥有最高评分的图书,以及这些作者哪些书评分最高。不过,在筛选时,我们会过滤掉评分人数少于 1000 的作者。
从上述结果可见,评分人数超过 1000 的最高评分前三本书是 Inner Engineering: A Yogi’s Guide to Joy、Bhagavad-Gita (Hindi) 和 The Alchemist。
上图按降序显示了评分人数超过 1000 且评分最高的前 10 位作者,分别是 Sadhguru、A. C. Bhaktivedanta 和 Paulo Coelho。
评分人数最多的作者与图书
虽然我们已经看过最高评分的图书和作者,但基于为该书打分的客户数量来评估最佳作者与图书会更具说服力与可信度。
那么,我们就快速找出来。
上图是作者的评分与评分人数的散点图。结合该图,可以得出以下结论。
结语
恭喜您完成本教程。
本教程介绍了如何使用 Beautiful Soup 抓取亚马逊的数据,以及如何借助 bokeh 绘图库对提取信息进行可视化以获取洞见。想继续深入学习使用 Beautiful Soup 进行网页抓取的一个不错练习,是去抓取其他网站的数据,看看能从中获得哪些见解。如果您想获取更多关于抓取热门网站的指导,我们还有一篇关于抓取 Reddit 的教程。
如果您刚开始学习 Python 并希望了解更多内容,欢迎学习 DataCamp 的Python 数据科学入门课程。