在本Python Web Scraping教程中,我们将概述开始Web Scraping所需的所有内容。我们将从简单的示例开始,逐步过渡到相对更复杂的示例。
项目描述
Python Web Scraping 教程:分步进行
目录
在本Python Web Scraping教程中,我们将概述开始Web Scraping所需的所有内容。我们将从简单的示例开始,逐步过渡到相对更复杂的示例。
Python可能是最适合Web Scraping的编程语言,因为它简单且拥有丰富的开源库。一些库使得提取数据并将其转换为所需格式的操作变得容易,无论是简单的CSV,还是更受程序员欢迎的JSON,甚至是直接保存到数据库。
使用Python进行Web Scraping非常简单,只需要5行代码即可完成。
5行代码实现Web Scraping
将这些五行代码写入任何文本编辑器中,保存为.py
文件,然后用Python运行。请注意,此代码假设您已安装了库。有关更多内容,请参阅下文。
import requests
from bs4 import BeautifulSoup
response = requests.get("https://en.wikipedia.org/wiki/Web_scraping")
bs = BeautifulSoup(response.text,"lxml")
print(bs.find("p").text)
这将跳转到网络爬取的维基百科页面,并在终端打印第一段。此代码展示了Python的简洁和强大。您可以在webscraping_5lines.py
文件中找到此代码。
Python代码中Web Scraping的组成部分
任何网络爬取代码的主要构建块如下:
- 获取HTML
- 将HTML解析为Python对象
- 保存提取的数据
在大多数情况下,没有必要使用浏览器来获取HTML。虽然HTML包含数据,但浏览器加载的其他文件(如图像、CSS、JavaScript等)只是使网站看起来更美、功能更齐全。网络爬取专注于数据。因此,在大多数情况下,没有必要获取这些辅助文件。
有些情况下,您确实需要打开浏览器。Python也使这变得很容易。
Python库
由于有许多有用的库可用,Python网络爬取变得很容易。
Python的裸机安装不足以进行网络爬取。Python的优势之一是拥有大量的网络爬取库。对于这个Python网络爬取教程,我们将使用三个重要的库——requests、BeautifulSoup和CSV。
- Requests库用于获取HTML文件,绕过使用浏览器的需要
- BeautifulSoup用于将原始HTML转换为Python对象,也称为解析。我们将使用该库的第四个版本,也称为
bs4
或BeautifulSoup4
。 - CSV库是Python标准安装的一部分。不需要单独安装。
- 通常,使用虚拟环境来安装这些库。如果您不知道虚拟环境,您可以在用户文件夹中安装这些库。
要安装这些库,启动您操作系统的终端或命令提示符,并输入:
pip install requests BeautifulSoup4 lxml
根据您的操作系统和设置,您可能需要使用pip3
而不是pip
。根据您的设置,您可能还需要使用--user
开关。
Python Web Scraping:使用Requests进行操作
requests库消除了启动浏览器、加载网页及其支持文件(使网站看起来更美)的需求。我们需要提取的数据都在HTML中。Requests库允许我们向网页发送请求并获取响应HTML。
打开您选择的文本编辑器,Visual Studio Code、PyCharm、Sublime Text、Jupyter Notebooks或甚至记事本。使用您熟悉的编辑器。
输入以下三行代码:
import requests
url_to_parse = "https://en.wikipedia.org/wiki/Python_(programming_language)"
response = requests.get(url_to_parse)
print(response)
将此文件保存为以.py
扩展名的Python文件,并从您的终端运行它。输出应该如下所示:
<Response (200)>
这意味着已收到响应,状态码为200。HTTP响应代码200表示成功的响应。范围在400到500之间的响应代码表示错误。您可以在此处了解有关响应代码的更多信息:这里。
要获取响应对象的HTML,我们可以简单地使用.text
属性。
print(response.text)
这将打印HTML到终端。前几个字符可能如下所示:
<!DOCTYPE html>
<html class="client-nojs" lang=" ...
如果我们检查数据类型,它将是一个字符串。下一步是将这个字符串转换为可以查询以找到特定信息的东西。
认识BeautifulSoup!
BeautifulSoup
Beautiful Soup提供了简单的导航、搜索和修改HTML的方法。它通过自动转换为UTF-8来处理编码。Beautiful Soup位于流行的Python解析器(如lxml和html5lib)之上。您可以直接使用lxml直接查询文档,但BeautifulSoup允许您尝试不同的解析策略而无需更改代码。
第一步是决定你想要使用的解析器。通常,lxml
是最常用的。这需要单独安装。
pip install lxml
一旦安装了 beautifulsoup4
和 lxml
,我们就可以创建一个 BeautifulSoup 对象。
soup = BeautifulSoup(response_text, 'lxml')
现在我们可以访问一些查询 HTML 元素的方法。例如,要获取页面的标题,我们只需像访问属性一样访问标签名。
print(soup.title)
# OUTPUT:
# <title>Python (programming language) - Wikipedia</title>
print(soup.title.text)
# OUTPUT:
# Python (programming language) - Wikipedia
请注意,要获取元素内的文本,我们只需使用 text
属性。
同样,soup.h1
将返回它找到的第一个 h1
标签。
print(soup.h1)
# OUTPUT:
# <h1 class="firstHeading" id="firstHeading">Python (programming language)</h1>
BeautifulSoup4中的查找方法
最常用的方法可能是 find()
和 find_all()
。让我们打开维基百科页面,获取目录。
find 方法的签名看起来像这样
find(name=None, attrs={}, recursive=True, text=None, **kwargs)
很明显,find 方法可以根据 name
、attributes
或 text
来查找元素。这应该涵盖了大多数情况。对于像通过 class
查找这样的场景,存在 **kwargs
可以接受其他过滤器。
继续维基百科示例,第一步是查看要提取的目录的 HTML 标记。右键单击包含目录的 div 并检查其标记。很明显,整个目录都在一个类属性设置为 toc 的 div 标签中。
<div id="toc" class="toc">
如果我们简单地运行 soup.find("div")
,它将返回它找到的第一个 div - 类似于编写 soup.div
。这需要过滤,因为我们需要一个特定的 div。幸运的是,这个 div 有一个 id
属性。以下代码可以提取 div 元素。
soup.find("div",id="toc")
请注意,这里的第二个参数是 id="toc"
。find 方法没有名为 id
的命名参数,但仍然有效,因为使用了 **kwargs
实现的过滤器。
不过要小心 CSS 类。在 Python 中,class
是一个保留关键字。它不能直接用作参数名称。有两种解决方案 - 一种是用 class_
代替 class
,另一种是用字典作为第二个参数。
这意味着以下两个语句是相同的
soup.find("div",class_="toc") #not the underscore
soup.find("div",{"class": "toc"})
使用字典的优势是可以指定多个属性。例如,如果你需要指定类和 id,你可以使用以下方式使用 find 方法
soup.find("div",{"class": "toc", "id":"toc"})
如果我们需要查找多个元素怎么办?
查找多个元素
考虑这个场景 - 目标是创建一个 CSV 文件,其中有两列。第一列包含标题编号,第二列包含标题文本。
要查找多个列,我们可以使用 find_all
方法。
此方法与 find 方法的工作方式相同,只是返回一个匹配条件的所有元素的列表,而不仅仅是单个元素。如果我们查看源代码,我们可以看到所有标题文本都在一个带有 toctext
类的 span
标签内。我们可以使用 find_all 方法提取这些。
soup.find_all("span",class_="toctext")
这将返回一个元素列表。
[<span class="toctext">History</span>,
<span class="toctext">Design philosophy and features</span>,
<span class="toctext">Syntax and semantics</span>,
<span class="toctext">Indentation</span>,
.....]
同样,标题编号可以使用此语句提取
soup.find_all("span",class_="tocnumber")
这将返回一个元素列表。
[<span class="tocnumber">1</span>,
<span class="tocnumber">2</span>,
<span class="tocnumber">3</span>,
<span class="tocnumber">3.1</span>,
...]
然而,我们需要一个包含编号和文本的列表。
查找嵌套元素
我们需要退一步查看标记。整个目录可以使用此语句选择
table_of_contents = soup.find("div",id="toc")
如果我们查看标记,我们可以看到每个标题编号和文本都在一个 li
标签内。
BeautifulSoup 的一个伟大功能是,find
和 find_all
方法也可以用于 WebElements
。在上面的例子中,whole_toc
是 WebElement
的一个实例。我们可以在这个元素内找到所有 li 标签。
headings = table_of_contents.find_all("li")
现在我们有一个元素列表。所有这些单个元素都包含标题文本和标题编号。一个简单的 for 循环可以用来创建一个字典,并将其添加到一个列表中。
data= []
for heading in headings:
heading_text = heading.find("span", class_="toctext").text
heading_number = heading.find("span", class_="tocnumber").text
data.append({
'heading_number' : heading_number,
'heading_text' : heading_text,
})
如果打印这些数据,它将是一个字典列表。
[{'heading_number': '1', 'heading_text': 'History'},
{'heading_number': '2', 'heading_text': 'Design philosophy and features'},
{'heading_number': '3', 'heading_text': 'Syntax and semantics'},
{'heading_number': '3.1', 'heading_text': 'Indentation'},
{'heading_number': '3.2', 'heading_text': 'Statements and control flow'},
.....]
现在可以使用 CSV 模块轻松导出这些数据。
导出数据
可以使用csv模块轻松将数据导出为CSV文件。第一步是以写入模式打开一个文件。请注意,应将newline
参数设置为空字符串。如果不这样做,你将在CSV文件中看到意外的换行符。
file= open("toc.csv", "w", newline="")
之后,创建DictWriter对象的实例。这需要一个标题列表。在我们的情况下,这些将只是数据中的字典键。
writer = csv.DictWriter(file,fieldnames=['heading_number','heading_text'])
可选地,写入标题然后调用write.writerows()
方法来写入data
。要写入一行,使用writerow()
方法。要写入所有行,也使用writerow()
方法。
writer.writeheader()
writer.writerows(data)
就是这样!我们已经将数据准备好了,存放在CSV中。
您可以在wiki_toc.py
文件中找到此完整代码。
其他工具
一些网站没有在HTML中包含数据,而是使用JavaScript从其他文件加载。在这种情况下,您需要一个使用浏览器的解决方案。一个完美的例子就是使用Selenium。我们在这里有一个Selenium的详细指南。
项目详情
python_web_scraping_tutorial_step_by_step-0.1.0-py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 129ed2184332f981b02b622691d22764a649b002b05ca6be2961856529e419a0 |
|
MD5 | 4c9366e032c483058605b2b0388ae0d4 |
|
BLAKE2b-256 | f7b5efcfb83b3447d2c19a15ecde4c63a086e7f78c88eabeaf73e5d4421ad502 |