栏目分类:
子分类:
返回
文库吧用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
文库吧 > IT > 软件开发 > 后端开发 > Python

python 爬虫热身篇 使用 requests 库通过 HTTP 读取网络数据,使用 pandas 读取网页上的表格,使用 Selenium 模拟浏览器操作

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

python 爬虫热身篇 使用 requests 库通过 HTTP 读取网络数据,使用 pandas 读取网页上的表格,使用 Selenium 模拟浏览器操作

引言

在过去,收集数据是一项繁琐的工作,有时非常昂贵。机器学习项目不能没有数据。幸运的是,我们现在在网络上有很多数据可供我们使用。我们可以从 Web 复制数据来创建数据集。我们可以手动下载文件并将其保存到磁盘。但是,我们可以通过自动化数据收集来更有效地做到这一点。Python中有几种工具可以帮助自动化。

完成本教程后,您将学习:

  • 如何使用 requests 库通过 HTTP 读取网络数据
  • 如何使用 pandas 读取网页上的表格
  • 如何使用 Selenium 模拟浏览器操作
概述

本教程分为三个部分;它们是:

  • 使用 requests 库
  • 使用 panda 在网络上阅读表格
  • 用 selenium 阅读动态内容
使用requests库

当我们谈论编写Python程序从Web上读取时,不可避免的是我们无法避免requests库。您需要安装它(以及我们稍后将介绍的BeautifulSoup和lxml):

pip install requests beautifulsoup4 lxml

它为您提供了一个界面,可让您轻松与网络进行交互。

非常简单的用例是从URL读取网页:

import requests

# Lat-Lon of New York
URL = "https://weather.com/weather/today/l/40.75,-73.98"
resp = requests.get(URL)
print(resp.status_code)
print(resp.text)

运行结果:

如果您熟悉 HTTP,您可能还记得状态代码 200 表示请求已成功完成。然后我们可以阅读响应。在上面,我们阅读文本响应并获取网页的HTML。如果它是CSV或其他一些文本数据,我们可以在响应对象的属性中获取它们。例如text,这就是我们从美联储经济学数据中读取CSV的方法:

以下例子会用到pandas 模块 :

安装: pip install pandas -i https://pypi.tuna.tsinghua.edu.cn/simple

import io
import pandas as pd
import requests

URL = "https://fred.stlouisfed.org/graph/fredgraph.csv?id=T10YIE&cosd=2017-04-14&coed=2022-04-14"
resp = requests.get(URL)
if resp.status_code == 200:
   csvtext = resp.text
   csvbuffer = io.StringIO(csvtext)
   df = pd.read_csv(csvbuffer)
   print(df)

运行结果:

如果数据是JSON的形式,我们可以将其读取为文本,甚至可以为您解码。例如,以下是以JSON格式从GitHub中提取一些数据并将其转换为Python字典:

import requests

URL = "https://api.github.com/users/jbrownlee"
resp = requests.get(URL)
if resp.status_code == 200:
    data = resp.json()
    print(data)

运行结果:

但是,如果 URL 为您提供了一些二进制数据,例如 ZIP 文件或 JPEG 图像,则需要在属性中获取它们,因为这将是二进制数据。例如,这就是我们下载图像(维基百科的标志)的方式:

import requests

URL = "https://en.wikipedia.org/static/images/project-logos/enwiki.png"
wikilogo = requests.get(URL)
if wikilogo.status_code == 200:
    with open("enwiki.png", "wb") as fp:
        fp.write(wikilogo.content)

运行结果:

鉴于我们已经获得了网页,我们应该如何提取数据?这超出了requests所能提供给我们的范围,但我们可以使用不同的library 来提供帮助。有两种方法可以做到这一点,这取决于我们想要如何指定数据。

第一种方法是将 HTML 视为一种 XML 文档,并使用 XPath 语言提取元素。在这种情况下,我们可以利用该库首先创建一个文档对象模型(DOM),然后通过XPath进行搜索:

import requests
from lxml import etree



URL = "https://weather.com/weather/today/l/40.75,-73.98"
resp = requests.get(URL)

# 从HTML文本创建DOM
dom = etree.HTML(resp.text)
# 搜索温度元素并获得内容
elements = dom.xpath("//span[@data-testid='TemperatureValue' and contains(@class,'CurrentConditions')]")
print(elements[0].text)

XPath 是一个字符串,它指定如何查找元素。lxml 对象提供了一个函数,用于在 DOM 中搜索与 XPath 字符串匹配的元素,这些元素可以是多个匹配项。上面的 XPath 意味着在具有标记和属性与 “” 匹配且以 “” 开头的任何位置查找 HTML 元素。我们可以通过检查HTML源代码从浏览器的开发人员工具(例如,下面的Chrome屏幕截图)中学习这一点。xpath()````data-testid``TemperatureValue``class``CurrentConditions

这个例子是找到纽约市的温度,由我们从这个网页获得的这个特定元素提供。我们知道与 XPath 匹配的第一个元素是我们需要的,我们可以读取标记内的文本。

另一种方法是在HTML文档上使用CSS选择器,我们可以利用BeautifulSoup库:

import requests
from bs4 import BeautifulSoup



URL = "https://weather.com/weather/today/l/40.75,-73.98"
resp = requests.get(URL)

soup = BeautifulSoup(resp.text, "lxml")
elements = soup.select('span[data-testid="TemperatureValue"][class^="CurrentConditions"]')
print(elements[0].text)

运行结果:

在上面,我们首先将HTML文本传递给BeautifulSoup。BeautifulSoup支持各种HTML解析器,每个解析器具有不同的功能。在上面,我们使用库作为BeautifulSoup推荐的解析器(它通常也是最快的)。CSS选择器是一种不同的迷你语言,与XPath相比有优点和缺点。上面的选择器与我们在上一个示例中使用的 XPath 相同。因此,我们可以从第一个匹配的元素中获得相同的温度。

以下是根据网络上的实时信息打印纽约当前温度的完整代码:

import requests
from bs4 import BeautifulSoup
from lxml import etree


URL = "https://weather.com/weather/today/l/40.75,-73.98"
resp = requests.get(URL)

if resp.status_code == 200:
    # Using lxml
    dom = etree.HTML(resp.text)
    elements = dom.xpath("//span[@data-testid='TemperatureValue' and contains(@class,'CurrentConditions')]")
    print(elements[0].text)

    # Using BeautifulSoup
    soup = BeautifulSoup(resp.text, "lxml")
    elements = soup.select('span[data-testid="TemperatureValue"][class^="CurrentConditions"]')
    print(elements[0].text)

可以想象,您可以通过定期运行此脚本来收集温度的时间序列。同样,我们可以从各种网站自动收集数据。这就是我们为机器学习项目获取数据的方法。

使用 panda 在网络上阅读表格

通常,网页将使用表格来承载数据。如果页面足够简单,我们甚至可以跳过检查它以找出XPath或CSS选择器,并使用pandas一次性获取页面上的所有表格。它很简单,可以在一行中完成:

import pandas as pd

tables = pd.read_html("https://www.federalreserve.gov/releases/h10/current/")
print(tables)
[                               Instruments 2022Apr7 2022Apr8 2022Apr11 2022Apr12 2022Apr13
0          Federal funds (effective) 1 2 3     0.33     0.33      0.33      0.33      0.33
1                 Commercial Paper 3 4 5 6      NaN      NaN       NaN       NaN       NaN
2                             Nonfinancial      NaN      NaN       NaN       NaN       NaN
3                                  1-month     0.30     0.34      0.36      0.39      0.39
4                                  2-month     n.a.     0.48      n.a.      n.a.      n.a.
5                                  3-month     n.a.     n.a.      n.a.      0.78      0.78
6                                Financial      NaN      NaN       NaN       NaN       NaN
7                                  1-month     0.49     0.45      0.46      0.39      0.46
8                                  2-month     n.a.     n.a.      0.60      0.71      n.a.
9                                  3-month     0.85     0.81      0.75      n.a.      0.86
10                   Bank prime loan 2 3 7     3.50     3.50      3.50      3.50      3.50
11      Discount window primary credit 2 8     0.50     0.50      0.50      0.50      0.50
12              U.S. government securities      NaN      NaN       NaN       NaN       NaN
13   Treasury bills (secondary market) 3 4      NaN      NaN       NaN       NaN       NaN
14                                  4-week     0.21     0.20      0.21      0.19      0.23
15                                 3-month     0.68     0.69      0.78      0.74      0.75
16                                 6-month     1.12     1.16      1.22      1.18      1.17
17                                  1-year     1.69     1.72      1.75      1.67      1.67
18            Treasury constant maturities      NaN      NaN       NaN       NaN       NaN
19                               Nominal 9      NaN      NaN       NaN       NaN       NaN
20                                 1-month     0.21     0.20      0.22      0.21      0.26
21                                 3-month     0.68     0.70      0.77      0.74      0.75
22                                 6-month     1.15     1.19      1.23      1.20      1.20
23                                  1-year     1.78     1.81      1.85      1.77      1.78
24                                  2-year     2.47     2.53      2.50      2.39      2.37
25                                  3-year     2.66     2.73      2.73      2.58      2.57
26                                  5-year     2.70     2.76      2.79      2.66      2.66
27                                  7-year     2.73     2.79      2.84      2.73      2.71
28                                 10-year     2.66     2.72      2.79      2.72      2.70
29                                 20-year     2.87     2.94      3.02      2.99      2.97
30                                 30-year     2.69     2.76      2.84      2.82      2.81
31                    Inflation indexed 10      NaN      NaN       NaN       NaN       NaN
32                                  5-year    -0.56    -0.57     -0.58     -0.65     -0.59
33                                  7-year    -0.34    -0.33     -0.32     -0.36     -0.31
34                                 10-year    -0.16    -0.15     -0.12     -0.14     -0.10
35                                 20-year     0.09     0.11      0.15      0.15      0.18
36                                 30-year     0.21     0.23      0.27      0.28      0.30
37  Inflation-indexed long-term average 11     0.23     0.26      0.30      0.30      0.33,  

pandas 中的函数read_html()读取 URL 并查找页面上的所有表。每个表都转换为 pandas DataFrame,然后在列表中返回所有表。在这个例子中,我们正在阅读美联储的各种利率,而美联储恰好在这个页面上只有一个表格。表列由 pandas 自动标识。

很可能并非所有表格都是我们感兴趣的。有时,网页会使用表格作为格式化页面的一种方式,但熊猫可能不够聪明, 无法分辨。因此,我们需要测试并挑选函数返回的结果。

用硒阅读动态内容

现代网页的很大一部分充满了JavaScript。这给了我们一个更奇特的体验,但成为一个障碍,用作提取数据的程序。一个例子是雅虎的主页,如果我们只加载页面并找到所有新闻标题,那么在浏览器上看到的要少得多:

import requests

# Read Yahoo home page
from lxml import etree

URL = "https://www.yahoo.com/"
resp = requests.get(URL)
dom = etree.HTML(resp.text)

# Print news headlines
elements = dom.xpath("//h3/a[u[@class='StretchedBox']]")
for elem in elements:
    print(etree.tostring(elem, method="text", encoding="unicode"))

运行结果:

这是因为像这样的网页依靠JavaScript来填充内容。著名的Web框架,如AngularJS或React,是这一类别的幕后推手。Python 库,比如requests ,不理解 JavaScript。因此,您将看到不同的结果。如果你想从网上获取的数据就是其中之一,你可以研究JavaScript是如何被调用的,并在你的程序中模仿浏览器的行为。但这可能太乏味了,无法使其正常工作。

另一种方法是要求真正的浏览器读取网页,而不是使用requests。这就是selenium可以做的。在使用它之前,我们需要安装库:

pip install selenium

但Selenium只是一个控制浏览器的框架。您需要在计算机上安装浏览器以及将Selenium连接到浏览器的驱动程序。如果您打算使用Chrome,则还需要下载并安装ChromeDriver。您需要将驱动程序chromedriver放在可执行路径中,以便Selenium可以像普通命令一样调用它。

同样,如果你使用的是Firefox,你需要GeckoDriver。有关设置Selenium的更多详细信息,请参阅其文档。

之后,您可以使用 Python 脚本来控制浏览器行为。例如:

import time
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By

# Launch Chrome browser in headless mode
options = webdriver.ChromeOptions()
options.add_argument("headless")
browser = webdriver.Chrome(options=options)

# Load web page
browser.get("https://www.yahoo.com")


# Network transport takes time. Wait until the page is fully loaded
def is_ready(browser):
    return browser.execute_script(r"""
        return document.readyState === 'complete'
    """)


WebDriverWait(browser, 30).until(is_ready)

# Scroll to bottom of the page to trigger JavaScript action
browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
time.sleep(1)
WebDriverWait(browser, 30).until(is_ready)

# Search for news headlines and print
elements = browser.find_elements(By.XPATH, "//h3/a[u[@class='StretchedBox']]")
for elem in elements:
    print(elem.text)

# Close the browser once finish
browser.close()

上述代码的工作原理如下。我们首先以无外设模式启动浏览器,这意味着我们要求Chrome启动但不显示在屏幕上。如果我们想远程运行脚本,这很重要,因为可能没有任何GUI支持。请注意,每个浏览器的开发方式都不同,因此我们使用的选项语法特定于Chrome。如果我们使用Firefox,代码将是这样的:

options = webdriver.FirefoxOptions()
options.set_headless()
browser = webdriver.Firefox(firefox_options=options)

启动浏览器后,我们会为其提供一个要加载的 URL。但是,由于网络需要时间来交付页面,并且浏览器需要时间来呈现它,因此我们应该等到浏览器准备就绪后再继续下一个操作。我们检测浏览器是否已经使用 JavaScript 完成了渲染。我们让Selenium为我们运行JavaScript代码,并使用该函数告诉我们结果。我们利用Selenium的工具运行它,直到它成功或直到30秒超时。加载页面时,我们滚动到页面底部,以便可以触发JavaScript以加载更多内容。然后,我们无条件地等待一秒钟,以确保浏览器触发了JavaScript,然后等待页面再次准备就绪。之后,我们可以使用XPath(或者使用CSS选择器)提取新闻标题元素。由于浏览器是外部程序,因此我们负责在脚本中关闭它。

使用硒在几个方面与使用库不同。首先,您永远不会直接在Python代码中拥有Web内容。相反,您可以在需要时引用浏览器的内容。因此,该函数返回的Web元素引用外部浏览器内部的对象,因此在完成使用它们之前,我们不得关闭浏览器。其次,所有操作都应基于浏览器交互而不是网络请求。因此,您需要通过模拟键盘和鼠标移动来控制浏览器。但作为回报,您拥有支持JavaScript的全功能浏览器。例如,您可以使用 JavaScript 检查页面上某个元素的大小和位置,只有在呈现 HTML 元素后,您才会知道这些大小和位置。

Selenium框架提供了更多功能,我们可以在这里介绍。它功能强大,但是由于它连接到浏览器,因此使用它比库的要求更高,并且速度要慢得多。通常,这是从网络收集信息的最后手段。

延伸阅读

Python中另一个著名的Web爬行库,我们上面没有介绍过,那就是Scrapy。这就像将requests库与BeautifulSoup合并为一体一样。网络协议很复杂。有时我们需要管理网络 cookie 或使用 POST 方法为请求提供额外的数据。所有这些都可以通过具有不同函数或额外参数的请求库来完成。以下是一些资源供您深入了解:

转载请注明:文章转载自 www.wk8.com.cn
本文地址:https://www.wk8.com.cn/it/1037073.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 wk8.com.cn

ICP备案号:晋ICP备2021003244-6号