使用Python进行Web数据抓取:技术详解与实战示例

06-25 14阅读

在当今大数据时代,网络爬虫(Web Scraping) 已成为获取互联网信息的重要手段之一。无论是用于市场分析、舆情监控还是学术研究,网络爬虫都发挥着不可或缺的作用。本文将详细介绍如何使用 Python 编写一个简单的网页数据抓取程序,并结合实际案例展示其应用。


什么是网络爬虫?

网络爬虫(Web Crawler),也称为网页蜘蛛或网络机器人,是一种自动下载并解析网页内容的程序。它的核心功能包括:

发送HTTP请求获取网页HTML解析HTML文档提取目标数据存储数据到本地文件或数据库中

为什么选择Python?

Python 是目前最流行的网络爬虫开发语言之一,原因如下:

简洁易读的语法,适合快速开发强大的第三方库支持(如 requests, BeautifulSoup, Scrapy, Selenium)社区活跃,资源丰富

爬虫基本流程

发送请求:使用 requestsurllib 库向目标网站发起 HTTP 请求。解析页面:使用 BeautifulSouplxml 解析 HTML 页面结构。提取数据:根据 HTML 标签和属性定位所需数据。存储数据:将数据保存为 JSON、CSV 或数据库格式。

实战案例:抓取豆瓣电影 Top 250 的电影名称和评分

我们将以 豆瓣电影 Top 250 为例,编写一个 Python 脚本抓取每部电影的名称和评分。

4.1 安装依赖库

首先确保安装了以下 Python 库:

pip install requests beautifulsoup4 lxml

4.2 编写代码

import requestsfrom bs4 import BeautifulSoupimport csv# 设置请求头,模拟浏览器访问headers = {    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'}# 获取单页内容def get_page(url):    response = requests.get(url, headers=headers)    if response.status_code == 200:        return response.text    else:        print(f"请求失败,状态码:{response.status_code}")        return None# 解析单页内容def parse_page(html):    soup = BeautifulSoup(html, 'lxml')    items = soup.find_all('div', class_='item')    for item in items:        rank = item.find('em').text.strip()        title = item.find('span', class_='title').text.strip()        rating_tag = item.find('span', class_='rating_num')        rating = rating_tag.text.strip() if rating_tag else '暂无评分'        yield {            '排名': rank,            '电影名': title,            '评分': rating        }# 保存为CSV文件def save_to_csv(data, filename='douban_top250.csv'):    with open(filename, mode='w', encoding='utf-8-sig', newline='') as f:        writer = csv.DictWriter(f, fieldnames=['排名', '电影名', '评分'])        writer.writeheader()        writer.writerows(data)# 主函数def main():    base_url = "https://movie.douban.com/top250"    all_data = []    for i in range(0, 250, 25):  # 每页25条数据,共10页        url = f"{base_url}?start={i}"        html = get_page(url)        if html:            data = list(parse_page(html))            all_data.extend(data)            print(f"第 {i//25 + 1} 页数据已抓取完成,共 {len(data)} 条记录")    save_to_csv(all_data)    print("所有数据已保存完毕!")if __name__ == '__main__':    main()

代码解析说明

5.1 请求部分

我们使用 requests.get() 向豆瓣电影 Top 250 页面发送 GET 请求。设置 User-Agent 是为了防止被服务器识别为爬虫而拒绝访问。

5.2 解析部分

通过 BeautifulSouplxml 解析器,我们可以轻松地从 HTML 中提取结构化数据。例如:

find_all('div', class_='item'):找到所有电影条目。find('span', class_='title'):获取电影标题。find('span', class_='rating_num'):获取评分。

5.3 数据存储

我们使用 csv.DictWriter 将数据写入 CSV 文件,字段包括“排名”、“电影名”和“评分”。使用 utf-8-sig 编码是为了避免 Excel 打开时出现乱码。


注意事项与反爬机制应对策略

虽然我们完成了基本的数据抓取,但在实际应用中还需注意以下问题:

6.1 遵守 robots.txt 协议

每个网站根目录下通常有 robots.txt 文件,定义哪些路径可以被抓取。例如豆瓣的 robots.txt 地址是:https://www.douban.com/robots.txt

6.2 设置请求间隔

频繁请求容易触发网站的反爬机制,建议在每次请求之间加入随机延迟:

import timeimport randomtime.sleep(random.uniform(1, 3))  # 每次请求间隔1~3秒

6.3 使用代理 IP

如果遇到 IP 被封的情况,可以使用代理服务轮换 IP 地址:

proxies = {    'http': 'http://user:pass@ip:port',    'https': 'http://user:pass@ip:port'}requests.get(url, proxies=proxies)

进阶推荐:使用 Scrapy 框架

对于更复杂的爬虫项目,建议使用 Scrapy 框架。它提供了完整的爬虫架构,包括中间件、管道、日志等功能,适合构建大规模数据采集系统。


本文介绍了使用 Python 抓取网页数据的基本方法,并通过豆瓣电影 Top 250 的实战案例演示了整个流程。掌握这些技能后,你可以尝试爬取新闻、商品价格、股票数据等各类公开信息。

随着你对网络爬虫的理解加深,也可以进一步学习动态页面处理(如 Selenium)、分布式爬虫(如 Scrapy-Redis)等高级主题。


附录:完整代码一览

import requestsfrom bs4 import BeautifulSoupimport csvimport timeimport randomheaders = {    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36'}def get_page(url):    response = requests.get(url, headers=headers)    if response.status_code == 200:        return response.text    else:        print(f"请求失败,状态码:{response.status_code}")        return Nonedef parse_page(html):    soup = BeautifulSoup(html, 'lxml')    items = soup.find_all('div', class_='item')    for item in items:        rank = item.find('em').text.strip()        title = item.find('span', class_='title').text.strip()        rating_tag = item.find('span', class_='rating_num')        rating = rating_tag.text.strip() if rating_tag else '暂无评分'        yield {            '排名': rank,            '电影名': title,            '评分': rating        }def save_to_csv(data, filename='douban_top250.csv'):    with open(filename, mode='w', encoding='utf-8-sig', newline='') as f:        writer = csv.DictWriter(f, fieldnames=['排名', '电影名', '评分'])        writer.writeheader()        writer.writerows(data)def main():    base_url = "https://movie.douban.com/top250"    all_data = []    for i in range(0, 250, 25):        url = f"{base_url}?start={i}"        html = get_page(url)        if html:            data = list(parse_page(html))            all_data.extend(data)            print(f"第 {i//25 + 1} 页数据已抓取完成,共 {len(data)} 条记录")        time.sleep(random.uniform(1, 3))    save_to_csv(all_data)    print("所有数据已保存完毕!")if __name__ == '__main__':    main()

如需进一步扩展此项目,可添加更多字段(如导演、年份、类型等),或将数据导入 MySQL、MongoDB 等数据库中。欢迎继续探索 Python 网络爬虫的世界!

免责声明:本文来自网站作者,不代表CIUIC的观点和立场,本站所发布的一切资源仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负。本站信息来自网络,版权争议与本站无关。您必须在下载后的24个小时之内,从您的电脑中彻底删除上述内容。如果您喜欢该程序,请支持正版软件,购买注册,得到更好的正版服务。客服邮箱:ciuic@ciuic.com

目录[+]

您是本站第1208名访客 今日有42篇新文章

微信号复制成功

打开微信,点击右上角"+"号,添加朋友,粘贴微信号,搜索即可!