文章目录
在实际爬虫之前还需要了解和下载两个模块:BeautifulSoup和lxml。
BeautifulSoup
和 lxml
是Python中两个非常流行的库,它们在网页内容解析和数据提取方面非常有用。以下是关于这两个库的详细介绍:
BeautifulSoup
BeautifulSoup
是一个用于提取HTML和XML文件中数据的Python库。它能够通过你喜欢的解析器来解析网页,提供一些简单的方法和Pythonic的方式来导航、搜索和修改解析树。BeautifulSoup
的主要特点包括:
- 易于使用:提供了简洁的API,使得即使是新手也能快速上手。
- 可读性强:能够以可读的方式呈现解析后的文档结构。
- 灵活:支持多种解析器,如Python内置的
html.parser
,快速高效的lxml
,以及html5lib
等。 - 强大的搜索功能:可以轻松地通过标签名、属性等找到所需的元素。
- 广泛的文档和社区支持:拥有大量的文档和活跃的社区,方便查找解决方案。
lxml
lxml
是一个Python库,用于处理XML和HTML文件。它具有以下特点:
- 性能:
lxml
使用高效的libxml2库,因此在解析速度上通常比BeautifulSoup
使用的内置解析器快。 - 易用性:虽然
lxml
主要用于XML,但它也提供了对HTML的解析支持,且API直观易用。 - 功能丰富:除了基本的解析和元素查找功能外,
lxml
还支持XPath和XSLT,这使得在复杂的文档中进行数据提取变得更加容易。 - 兼容性:
lxml
能够处理不规范的HTML代码,容错性较好。
使用场景
- 当您需要快速解析HTML或XML文件,并从中提取数据时,
BeautifulSoup
是一个很好的选择,特别是当您需要一个易于学习和使用的库时。 - 如果性能是您的主要关注点,或者您需要处理大型文件和复杂的查询,
lxml
可能是更合适的选择。
BeautifulSoup
是一个可以从HTML或XML文件中提取数据的Python库。要安装 BeautifulSoup
,可以使用Python的包管理器 pip
。以下是安装步骤:
-
打开命令行界面(在Windows上是命令提示符或PowerShell,在macOS或Linux上是终端)。
-
输入以下命令来安装
beautifulsoup4
:
pip install beautifulsoup4
如果使用的是Python 3,并且系统同时安装了Python 2,可能需要使用 pip3
来代替 pip
:
pip3 install beautifulsoup4
- 等待安装完成。
此外,BeautifulSoup
需要一个解析器来解析网页,最常用的解析器是 lxml
或 html.parser
(Python标准库中包含)。html.parser
不需要额外安装,但 lxml
更快且能更好地处理不规范的HTML。如果想使用 lxml
作为解析器,可以使用以下命令安装:
pip install lxml
或者,如果使用的是Python 3:
pip3 install lxml
安装完成后,可以在Python脚本中导入并使用 BeautifulSoup
:
from bs4 import BeautifulSoup
具体代码
#!/usr/bin/python3
# -*- coding: utf-8 -*-
#Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36 Edg/124.0.0.0
#Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36
import requests
import json
from bs4 import BeautifulSoup
class TiebaSpider():
def __init__(self, kw, max_pn):
self.max_pn = max_pn
self.kw = kw
self.base_url = "https://tieba.baidu.com/f?kw={}&ie=utf-8&pn={}"
self.headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
}
pass
def get_url_list(self):
'''
获取 url 列表
:return:
'''
# 写法一
'''
url_list = []
for pn in range(0,self.max_pn,50):
url = self.base_url.format(self.kw,pn)
url_list.append(url)
return url_list
'''
# 写法二
return [self.base_url.format(self.kw, pn) for pn in range(0, self.max_pn, 50)]
def get_content(self, url):
'''
发送请求获取响应内容
:param url:
:return:
'''
response = requests.get(
url=url,
headers=self.headers
)
return response.content
# def get_items(self, content, index):
# '''
# 从响应内容中提取数据
# :param content:
# :return:
# '''
# with open('tieba-{}.html'.format(index), 'wb') as f:
# f.write(content)
# return None
def get_items(self, content, index):
'''
从响应内容中提取页面标题,并保存HTML内容到文件
:param content: HTML内容的字节串
:param index: 用于文件命名的索引
:return: 页面标题和URL的字典
'''
# 解析HTML内容
soup = BeautifulSoup(content, 'html.parser')
# 提取页面标题
title = soup.title.string if soup.title else '无标题'
# 构造URL,这里使用index作为页码
url = self.base_url.format(self.kw, index)
# 保存HTML内容到文件
with open(f'tieba-{index}.html', 'wb') as f:
f.write(content)
# 返回包含URL和标题的字典
return {'url': url, 'title': title}
# def save_items(self, items):
# '''
# 保存数据
# :param items:
# :return:
# '''
def save_items(self, items):
'''
保存提取的页面标题和URL到JSON文件
:param items: 字典,包含URL和标题
:return:
'''
# 检查items是否为None
if items is not None:
# 保存到JSON文件
with open(f'tieba-{items["url"].split("&pn=")[1]}.json', 'w', encoding='utf-8') as f:
json.dump(items, f, ensure_ascii=False, indent=4)
def run(self):
# 1. 获取 url 列表
url_list = self.get_url_list()
for url in url_list:
# 2. 发送请求获取响应
content = self.get_content(url)
# 3. 从响应中提取数据
items = self.get_items(content, url_list.index(url) + 1)
# 4. 保存数据
self.save_items(items)
pass
if __name__ == '__main__':
spider = TiebaSpider("英雄联盟", 150)
spider.run()
具体解析
1. 导入模块
import requests
import json
from bs4 import BeautifulSoup
这部分代码导入了三个库:requests
用于发送HTTP请求,json
用于处理JSON数据,BeautifulSoup
用于解析HTML。
2. 定义爬虫类
class TiebaSpider():
定义了一个名为TiebaSpider
的类,它将包含爬取数据的方法。
3. 初始化方法
def __init__(self, kw, max_pn):
self.max_pn = max_pn
self.kw = kw
self.base_url = "https://tieba.baidu.com/f?kw={}&ie=utf-8&pn={}" # 注意这里修复了HTML实体
self.headers = {
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.110 Safari/537.36"
}
__init__
方法初始化爬虫的关键词kw
,最大页码max_pn
,基础URLbase_url
(修复了HTML实体"
),以及包含User-Agent的请求头。
4. 获取URL列表
def get_url_list(self):
return [self.base_url.format(self.kw, pn) for pn in range(0, self.max_pn, 50)]
get_url_list
方法生成一个包含所有请求URL的列表。它使用列表推导式,根据页码范围生成URL。
5. 获取页面内容
def get_content(self, url):
response = requests.get(url=url, headers=self.headers)
return response.content
get_content
方法通过requests.get
发送GET请求,获取指定URL的页面内容。
6. 提取页面数据
def get_items(self, content, index):
soup = BeautifulSoup(content, 'html.parser')
title = soup.title.string if soup.title else '无标题'
url = self.base_url.format(self.kw, index)
with open(f'tieba-{index}.html', 'wb') as f:
f.write(content)
return {'url': url, 'title': title}
get_items
方法使用BeautifulSoup
解析页面内容,提取页面标题,并保存HTML到文件。然后返回一个包含URL和标题的字典。
7. 保存数据
def save_items(self, items):
if items is not None:
with open(f'tieba-{items["url"].split("&pn=")[1]}.json', 'w', encoding='utf-8') as f:
json.dump(items, f, ensure_ascii=False, indent=4)
save_items
方法检查items
是否为None
,然后尝试将items
字典保存为JSON文件。
8. 运行爬虫
def run(self):
url_list = self.get_url_list()
for url in url_list:
content = self.get_content(url)
items = self.get_items(content, url_list.index(url) + 1)
self.save_items(items)
run
方法是爬虫的主要逻辑,依次调用其他方法执行爬取任务。
9. 主程序
if __name__ == '__main__':
spider = TiebaSpider("英雄联盟", 150)
spider.run()
主程序创建TiebaSpider
的实例,传入关键词和最大页码,然后调用run
方法启动爬虫。
总结
这个爬虫程序通过发送HTTP请求获取页面内容,然后解析HTML以提取页面标题,并将页面内容保存为HTML文件。最后,它将每个页面的URL和标题保存为JSON文件。但是后续尝试将其中每篇文章的标题和url提取出来,有点翻车,明天再琢磨一下怎么解决。