python爬虫正则表达式使用说明

Python 爬虫和正则表达式是自动化网络数据提取中常用的两种技术。本文将详细介绍如何使用 Python 编写爬虫,结合正则表达式提取网页中的数据。

一、基础知识点

1. 安装必要库

爬虫通常需要使用库来处理 HTTP 请求和解析网页,常用库有:

  • requests:用于发送 HTTP 请求,获取网页内容。
  • re:Python 自带的正则表达式库,用于模式匹配和提取数据。
  • BeautifulSoup(可选):如果你需要更高级的网页解析,可以使用它。
pip install requests beautifulsoup4

2. 使用 requests 获取网页内容

你可以使用 requests 库获取网页的 HTML 内容。

import requests

url = "https://example.com"
response = requests.get(url)

# 获取网页内容(HTML 文本)
html_content = response.text

print(html_content)  # 输出网页的 HTML 源码

3. 正则表达式基础

正则表达式是一种模式匹配技术,用于从文本中提取特定格式的数据。Python 使用 re 模块来处理正则表达式。

3.1 常用正则表达式符号
  • .:匹配除换行符外的任意字符。
  • ^:匹配字符串的开头。
  • $:匹配字符串的结尾。
  • *:匹配 0 次或多次前面的字符。
  • +:匹配 1 次或多次前面的字符。
  • ?:匹配 0 次或 1 次前面的字符。
  • {n}:匹配 n 次前面的字符。
  • []:匹配括号中的任意字符,如 [abc] 匹配 abc
  • \d:匹配任意数字,相当于 [0-9]
  • \w:匹配任意字母、数字或下划线,相当于 [a-zA-Z0-9_]
  • \s:匹配空白字符(如空格、制表符)。
  • ():用来分组和提取匹配的子字符串。
3.2 基本示例
import re

text = "My phone number is 123-456-7890."

# 匹配电话号码
pattern = r"\d{3}-\d{3}-\d{4}"
match = re.search(pattern, text)

if match:
    print(f"匹配到的电话号码: {match.group()}")

在这个示例中,正则表达式 \d{3}-\d{3}-\d{4} 用来匹配类似于 123-456-7890 格式的电话号码。

4. 实战:使用 Python 爬虫和正则表达式抓取数据

下面我们将展示一个完整的实例,结合 Python 爬虫和正则表达式从网页上提取电子邮件地址。

4.1 获取网页 HTML
import requests

url = "https://example.com"
response = requests.get(url)
html_content = response.text
4.2 使用正则表达式提取邮箱地址
import re

# 定义正则表达式匹配邮箱地址
email_pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"

# 在网页内容中查找所有匹配的邮箱地址
emails = re.findall(email_pattern, html_content)

# 输出找到的邮箱
for email in emails:
    print(email)
4.3 从多个网页抓取数据(爬取多个页面)

如果你想从多个网页抓取数据,可以使用循环或递归,常见的做法是处理分页,或递归遍历多个 URL。

import requests
import re

# 爬取多个页面
for page_num in range(1, 6):
    url = f"https://example.com/page/{page_num}"
    response = requests.get(url)
    
    # 获取 HTML 内容
    html_content = response.text
    
    # 正则表达式提取信息
    email_pattern = r"[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}"
    emails = re.findall(email_pattern, html_content)
    
    # 打印提取的邮箱地址
    for email in emails:
        print(f"Page {page_num}: {email}")

5. 正则表达式高级技巧

5.1 捕获组和非捕获组
  • 捕获组 ():用于匹配和提取子字符串。例如 (\d{3})-(\d{3})-(\d{4}) 可以分别提取电话号码的各个部分。
  • 非捕获组 (?:):匹配但不提取。例如 (?:https?):// 匹配 httphttps 开头的 URL,但不捕获 httphttps
text = "My phone number is 123-456-7890."
pattern = r"(\d{3})-(\d{3})-(\d{4})"

match = re.search(pattern, text)
if match:
    area_code = match.group(1)  # 提取区号
    print(f"区号: {area_code}")
5.2 贪婪与非贪婪匹配
  • 默认情况下,*+ 是贪婪匹配,尽可能多地匹配字符。
  • 非贪婪匹配在贪婪符号后加 ?。例如,.*? 是非贪婪匹配,它会尽可能少地匹配字符。
text = "<div>First</div><div>Second</div>"

# 贪婪匹配,会匹配到整个字符串
greedy_match = re.search(r"<div>.*</div>", text)
print(greedy_match.group())  # 输出 "<div>First</div><div>Second</div>"

# 非贪婪匹配,只匹配到第一个 div
non_greedy_match = re.search(r"<div>.*?</div>", text)
print(non_greedy_match.group())  # 输出 "<div>First</div>"

6. 使用 BeautifulSoup 与正则表达式结合

BeautifulSoup 是一个功能强大的 HTML 解析库,适合处理复杂的 HTML 页面。你可以结合它和正则表达式更精确地提取网页数据。

from bs4 import BeautifulSoup
import requests
import re

url = "https://example.com"
response = requests.get(url)

# 使用 BeautifulSoup 解析 HTML
soup = BeautifulSoup(response.text, "html.parser")

# 提取所有链接
for a_tag in soup.find_all("a", href=True):
    href = a_tag['href']
    if re.match(r"https?://", href):  # 正则表达式匹配完整的 URL
        print(href)

7. 处理反爬机制

许多网站有反爬机制,如检测爬虫的 IP 或使用 JavaScript 动态加载内容。如果遇到这些问题,可以考虑以下技术:

  • 请求头模拟:模拟真实用户的请求头,避免被网站检测为爬虫。
headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36"
}
response = requests.get(url, headers=headers)
  • 使用代理:避免 IP 被封,可以使用代理池。
  • 处理动态内容:如果网页使用 JavaScript 加载数据,考虑使用 Selenium 这样的浏览器自动化工具或直接抓取网站 API 数据。

8. re 模块的主要函数

  • re.search():在字符串中搜索符合正则表达式的模式,返回第一个匹配。
  • re.findall():返回所有匹配的子串。
  • re.sub():使用另一个字符串替换所有匹配的子串。
  • re.match():只在字符串的开头进行匹配。
# 替换字符串中的所有数字
text = "Price: $45, Discount: 20%"
clean_text = re.sub(r'\d+', '[NUMBER]', text)
print(clean_text)  # 输出 "Price: $[NUMBER], Discount: [NUMBER]%"

二、综合应用示例:爬取并解析数据

我们使用爬虫抓取一个网页,并用正则表达式提取其中的邮箱地址和价格。

import requests
import re
from bs4 import BeautifulSoup

# 1. 下载网页
url = "https://example.com"
response = requests.get(url)
html = response.text

# 2. 使用 BeautifulSoup 解析网页
soup = BeautifulSoup(html, 'html.parser')

# 3. 从网页中提取文本信息
text = soup.get_text()

# 4. 正则表达式提取邮箱和价格
email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b'
price_pattern = r'\$\d+(\.\d{2})?'

emails = re.findall(email_pattern, text)
prices = re.findall(price_pattern, text)

# 5. 输出结果
print("Emails found:", emails)
print("Prices found:", prices)

优点:

  • 灵活性强,爬虫和正则结合可以应对多种网页和数据提取需求。
  • 正则表达式可以准确提取所需信息。

缺点:

  • 如果网页结构变化,爬虫代码需要修改,尤其是基于正则提取的部分。
  • 正则表达式对复杂的 HTML 结构不友好,不如 BeautifulSoup 处理嵌套标签那么直观。

三、动态网页处理

对于由 JavaScript 渲染的动态网页,使用 Selenium 等工具来加载网页并抓取数据。例如:

from selenium import webdriver

# 启动浏览器
driver = webdriver.Chrome()
driver.get("https://example.com")

# 等待页面加载
html = driver.page_source

# 使用 BeautifulSoup 解析动态内容
soup = BeautifulSoup(html, 'html.parser')

优点:

  • 可以处理动态内容和 AJAX 加载的网页。
  • Selenium 支持模拟用户行为(点击、输入等)。

缺点:

  • 速度较慢,因为需要模拟整个浏览器。
  • 占用更多系统资源,不适合大规模数据抓取。

结论

使用 Python 进行爬虫和正则表达式处理是非常强大的组合。requestsBeautifulSoup 适合处理静态网页,而正则表达式可以快速提取文本中的特定模式。然而,处理复杂网页时,爬虫的维护成本较高,特别是正则表达式对于动态网页或嵌套结构的处理较为局限。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yuwinter

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值