网络爬虫Xpath和Requests入门介绍及爬取图片应用

403 阅读6分钟

免责声明

本博客所提供的网络爬虫示例和相关技术仅供学习与研究用途,所有内容旨在帮助读者了解爬虫技术及其应用。我们不提倡或支持未经授权的爬取行为,所有示例代码和教程的使用者需遵守相关法律法规和目标网站的robots.txt协议。

什么是网页爬取?

网页爬取(Web Scraping)是通过编程从网站上提取数据的过程。它允许我们与网页的内容进行程序化交互,解析并提取页面中的信息,如文本、图片或链接。Python是进行网页爬取的热门编程语言,常用的库包括requestslxml

XPath介绍

XPath(XML Path Language)是一种用于在XML文档中查找信息的语言。它通过定义路径表达式来定位XML文档中的节点或元素。虽然XPath最初是为XML文档设计的,但它也被广泛应用于HTML文档的解析,特别是在Web爬虫和自动化测试中,常用于提取网页中的数据。

XPath路径表达式通过使用不同的语法来定位和筛选文档中的元素或属性。它支持多种查询方式,如从根节点、子节点、属性、文本内容等进行定位。

XPath语法基础

  1. 绝对路径:以/开头,表示从根节点开始查找。

    • 示例:/html/body/div 代表从html元素开始,找到其子元素bodydiv
  2. 相对路径:不以/开头,表示从当前节点开始查找。

    • 示例://div 代表查找所有div元素。
  3. 节点选择器

    • /:表示直接子节点。
    • //:表示从当前节点开始查找匹配的所有节点。
    • @:表示选择元素的属性。
    • text():选择元素的文本内容。
  4. 谓语(条件) :用[]表示,用于进一步过滤节点。

    • 示例://a[@href='https://example.com'] 表示选择href属性为https://example.com的所有a元素。

常见XPath用法与解析

(注:该部分涉及html知识)假设目标网页是一个包含多个图片和链接的新闻网页,常见的XPath查询方式包括:

  • 获取所有图片链接://img/@src
  • 获取所有文章链接://a/@href
  • 获取某个特定类的元素://div[@class='content']
  • 获取第一个<h1>标签的文本://h1/text()

常用XPath操作举例

1. 获取网页中的所有链接

假设网页中有多个<a>标签,并且我们想提取所有的链接(即href属性)。

from lxml import etree

html = """
<html>
    <body>
        <a href="https://www.example.com">Example 1</a>
        <a href="https://www.example2.com">Example 2</a>
    </body>
</html>
"""

tree = etree.HTML(html)
links = tree.xpath('//a/@href')  # 提取所有a标签的href属性
print(links)

输出:

['https://www.example.com', 'https://www.example2.com']

2. 获取网页中第一个<h1>标签的文本内容

html = """
<html>
    <body>
        <h1>Welcome to My Website</h1>
    </body>
</html>
"""

tree = etree.HTML(html)
header = tree.xpath('//h1/text()')  # 获取第一个h1标签的文本内容
print(header)

输出:

['Welcome to My Website']

3. 获取网页中所有图片的src属性(图片链接)

html = """
<html>
    <body>
        <img src="https://www.example.com/image1.jpg" />
        <img src="https://www.example2.com/image2.jpg" />
    </body>
</html>
"""

tree = etree.HTML(html)
images = tree.xpath('//img/@src')  # 获取所有img标签的src属性
print(images)

输出:

['https://www.example.com/image1.jpg', 'https://www.example2.com/image2.jpg']

4. 通过条件筛选元素

假设我们有一个包含多个<a>标签的页面,并且我们只想获取class属性为"special"的链接。

html = """
<html>
    <body>
        <a href="https://www.example.com" class="special">Example 1</a>
        <a href="https://www.example2.com" class="normal">Example 2</a>
    </body>
</html>
"""

tree = etree.HTML(html)
special_link = tree.xpath('//a[@class="special"]/@href')  # 筛选class属性为special的a标签
print(special_link)

输出:

['https://www.example.com']

5. 获取特定索引的元素

有时我们需要获取某个标签的特定位置元素,可以使用[n]来选择。例如,获取第二个<a>标签的href属性。

html = """
<html>
    <body>
        <a href="https://www.example1.com">Link 1</a>
        <a href="https://www.example2.com">Link 2</a>
        <a href="https://www.example3.com">Link 3</a>
    </body>
</html>
"""

tree = etree.HTML(html)
second_link = tree.xpath('(//a)[2]/@href')  # 获取第二个a标签的href属性
print(second_link)

输出:

['https://www.example2.com']

Request库介绍与结合XPath使用

requests库是Python中最常用的HTTP请求库之一,它使得发送HTTP请求变得非常简单。结合requestsXPath可以轻松实现网页内容的抓取与解析。下面,我们将结合requests库和XPath来实现一个简单的网页抓取和解析实例。

requests库用于发送HTTP请求(如GET、POST等),并处理响应内容。它的接口非常简洁,支持各种复杂的HTTP请求需求,同时支持自动处理Cookie、会话和重定向等。

安装requests库:

pip install requests

requests常用的请求方法:

  • requests.get(url):发送GET请求,获取网页内容。
  • requests.post(url, data):发送POST请求,提交表单数据。
  • response.text:获取网页的HTML内容。
  • response.json():获取JSON格式的响应内容。

2. 结合XPath与Requests获取图片

在网络爬虫中,常常需要获取网页的HTML内容,并通过XPath对内容进行解析。下面是一个完整的示例,展示如何使用requests获取网页内容,并用XPath解析和提取其中的特定数据。下面我们就以抓取网页中的图片链接并下载图片为例:

如果我们需要从一个网页中提取所有的图片链接(如下图一般在<img>标签的src属性),我们可以使用requests获取网页的HTML,再使用XPath来提取图片链接。 image.png

步骤:

  1. 使用requests.get()请求网页,获取HTML内容。
  2. 使用lxml库的XPath解析HTML并提取需要的数据。
import requests
from lxml import etree

# 1. 获取网页的HTML内容
url = 'https://example.com'  # 替换为目标网页的URL
response = requests.get(url)

# 2. 使用XPath解析网页
html_content = response.text  # 获取网页的HTML内容
tree = etree.HTML(html_content)  # 使用lxml将HTML内容转换为可解析的树形结构

# 3. 提取所有图片的src链接
image_links = tree.xpath('//img/@src')  # 提取所有img标签的src属性值

# 4. 打印图片链接
for link in image_links:
    print(link)

代码说明

  1. requests.get(url):获取网页内容,这里url为目标网页地址。response.text将返回网页的HTML内容。
  2. etree.HTML(html_content)lxmletree.HTML方法将HTML内容转换为树形结构,方便后续使用XPath来提取数据。
  3. tree.xpath('//img/@src'):使用XPath表达式//img/@src来提取所有<img>标签的src属性值,即图片的链接地址。

下一步:图片下载

如果我们要将所有提取的图片链接下载到本地,可以继续使用requests请求图片链接🔗,然后下载图片的二进制数据,并保存到本地中

import os

if not os.path.exists('images'):  # 如果没有images文件夹,则创建
    os.makedirs('images')

for i, link in enumerate(image_links, 1):
    # 如果链接是相对路径,补充完整URL
    if link.startswith('/'):
        link = url + link
    try:
        img_data = requests.get(link).content  # 获取图片二进制数据
        with open(f'images/image_{i}.jpg', 'wb') as f:
            f.write(img_data)  # 保存图片
        print(f"下载第{i}张图片成功!")
    except Exception as e:
        print(f"下载第{i}张图片失败:{e}")


image.png

进一步学习

在完成了基础的网页爬取后,接下来可以深入学习一些更高级的技术来提升爬虫的能力:

  1. 正则表达式: 正则表达式是用于匹配和操作字符串的强大工具。在网页爬取中,它可以帮助我们从HTML文本中提取特定的内容,尤其是当页面结构比较复杂,或者没有明确的标签时。通过学习正则表达式,你可以在HTML源码中精确地匹配需要的数据。你可以使用Python中的re库来应用正则表达式。
  2. Selenium: 如果你需要爬取的是动态加载的网页(即通过JavaScript加载内容的网页),传统的requestsXPath可能无法提取到你需要的数据。这时,Selenium成为一个强有力的工具。Selenium是一个自动化测试工具,但它也非常适合用于爬取动态网页。它通过模拟浏览器的行为来加载页面内容,帮助你抓取通过JavaScript渲染的数据。