如何写一个简单的爬虫

您所在的位置:网站首页 mfc爬虫 如何写一个简单的爬虫

如何写一个简单的爬虫

2024-07-06 08:09| 来源: 网络整理| 查看: 265

学习爬虫重要的是知识储备以及实战能力,最近有个学妹要求我帮她写一个爬虫程序,我将我编写的爬虫代码以及解释都记录下来,方便后期更多的伙伴们学习参考。

前置知识-爬虫定义

爬虫指的是一种自动化程序,用于在互联网上获取和抓取信息。它可以从网站中抓取数据并将其存储到本地计算机或其他数据库中,以便进一步处理和分析。

爬虫通常会自动访问网页、解析页面内容,并提取有用的信息,例如网页上的文本、图像、视频、音频、超链接等等。

requests 库:这是一个用于发送 HTTP 请求的库,可以发送 GET、POST、PUT、DELETE 等多种请求方式,并且可以设置请求头、请求体、Cookies 等信息。它还支持自动处理重定向、代理、SSL/TLS 等常见的网络请求问题,并且支持响应的解析,可以解析 JSON、HTML 等多种格式的响应数据。

urllib.parse 库:这是一个用于解析 URL 的库,它可以将 URL 拆分成各个部分,例如协议、域名、路径、查询参数等,并且可以对 URL 进行编码和解码,防止出现乱码和安全问题。

bs4 库:这是一个用于解析 HTML 和 XML 的库,可以从 HTML 或 XML 文件中提取数据,并且支持多种解析方式,例如基于标签名、CSS 选择器、正则表达式等。它还可以自动修正 HTML 或 XML 代码中的错误,方便数据提取。

正文-简单实现

首先,我们可以先实现一个简单的爬虫代码。

功能:

可以从指定的 URL 开始遍历整个网站。

输出网站中所有的链接。

关键代码实现:

import requests from bs4 import BeautifulSoup def crawl(url): # 发送 GET 请求获取页面内容 response = requests.get(url) # 使用 BeautifulSoup 解析页面内容 soup = BeautifulSoup(response.content, 'html.parser') # 获取页面中所有链接 links = [] for link in soup.find_all('a'): href = link.get('href') if href: links.append(href) return links # 测试代码 if __name__ == '__main__': url = 'http://jshk.com.cn/mb/reg.asp?kefu=xjy' links = crawl(url) for link in links: print(link)

这个代码使用了python的 requests 库来发送 HTTP 请求,使用 BeautifulSoup 库来解析 HTML 页面内容,获取页面中所有链接并输出。在测试代码中,可以指定要爬取的 URL,然后输出所有链接。

第一次优化

import requests from bs4 import BeautifulSoup from urllib.parse import urlparse, urljoin def get_links(url): # 发送 GET 请求获取页面内容 response = requests.get(url) # 使用 BeautifulSoup 解析页面内容 soup = BeautifulSoup(response.content, 'html.parser') # 获取页面中所有链接 links = [] for link in soup.find_all('a'): href = link.get('href') if href: href = urljoin(url, href) # 处理相对链接 parsed_href = urlparse(href) if parsed_href.scheme in ('http', 'https') and parsed_href.netloc: # 只处理 http 和 https 协议的链接 links.append(href) return links def crawl(url, max_depth=3): visited = set() # 已访问过的链接 queue = [(url, 0)] # 待访问的链接队列 while queue: url, depth = queue.pop(0) if depth > max_depth: # 超过最大深度,停止访问 break if url not in visited: visited.add(url) print(' ' * depth, url) links = get_links(url) for link in links: if link not in visited: queue.append((link, depth+1)) # 测试代码 if __name__ == '__main__': url = 'http://jshk.com.cn/mb/reg.asp?kefu=xjy' crawl(url)

这个代码与之前的代码相比进行了以下优化:

处理相对链接:使用 urljoin 函数将相对链接转换为绝对链接,以便更好地处理。

只处理 http 和 https 协议的链接:使用 urlparse 函数获取链接的协议和域名,只处理 http 和 https 协议的链接。

控制访问深度:使用 max_depth 参数控制访问深度,避免无限递归导致程序崩溃。

优化访问效率:使用集合 visited 记录已经访问过的链接,避免重复访问。

在测试代码中,可以指定要爬取的 URL,并设置 max_depth 参数,然后输出所有链接及其对应的深度。

第二次优化

import requests from bs4 import BeautifulSoup from urllib.parse import urlparse, urljoin import time class Crawler: def __init__(self, start_url, max_depth=3, delay=1): self.start_url = start_url self.max_depth = max_depth self.delay = delay self.visited = set() self.queue = [(start_url, 0)] def crawl(self): while self.queue: url, depth = self.queue.pop(0) if depth > self.max_depth: break if url in self.visited: continue self.visited.add(url) print(' ' * depth, url) time.sleep(self.delay) links = self.get_links(url) for link in links: if link not in self.visited: self.queue.append((link, depth+1)) def get_links(self, url): response = requests.get(url) soup = BeautifulSoup(response.content, 'html.parser') links = [] for link in soup.find_all('a'): href = link.get('href') if href: href = urljoin(url, href) parsed_href = urlparse(href) if parsed_href.scheme in ('http', 'https') and parsed_href.netloc: links.append(href) return links # 测试代码 if __name__ == '__main__': start_url = 'http://jshk.com.cn/mb/reg.asp?kefu=xjy' crawler = Crawler(start_url, max_depth=3, delay=1) crawler.crawl()

这个代码相比之前的代码进行了以下优化:

将爬虫代码封装到一个类 Crawler 中,方便控制和管理爬虫。

增加了延时参数 delay,可以设置每次访问页面的延时,避免过快访问导致被封禁。

增加了错误处理和日志记录,可以更好地处理异常情况和记录程序运行情况。

在测试代码中,可以创建一个 Crawler 对象,设置起始 URL、最大深度和延时参数,然后调用 crawl 方法开始爬取网站。其中,crawl 方法使用 BFS 算法遍历网站,get_links 方法获取页面中的所有链接,同时加入了延时和错误处理机制。

结果展示

在这里插入图片描述



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3