Python网络爬虫从零基础到精通教程1. 环境准备与PyCharm 2021配置首先您需要在计算机上安装Python和PyCharm 2021。以下是详细步骤1.1 安装Python访问Python官网https://www.python.org/downloads/下载最新稳定版推荐Python 3.8安装时务必勾选Add Python to PATH选项。1.2 安装PyCharm 2021访问JetBrains官网下载PyCharm 2021 Community版免费运行安装程序按默认设置完成安装首次启动时建议进行以下配置选择深色主题如Darcula保护眼睛安装中文语言包可选设置合适的字体大小推荐14-16px1.3 创建第一个Python项目# 在PyCharm中创建新项目步骤 # 1. File → New Project # 2. 选择项目位置和解释器自动检测已安装的Python # 3. 右键项目 → New → Python File # 4. 输入文件名如first_crawler.py2. 网络爬虫基础概念网络爬虫Web Crawler是一种自动化程序用于从互联网上抓取数据。其主要工作流程如下组件功能描述对应工具/库URL管理器管理待抓取和已抓取的URL队列列表/集合网页下载器下载网页内容requests库网页解析器提取所需数据BeautifulSoup数据存储器保存抓取结果文件/数据库3. 核心库安装与使用在PyCharm的Terminal中执行以下命令安装必要库# 安装requests库用于网页下载 pip install requests # 安装BeautifulSoup4用于网页解析 pip install beautifulsoup4 # 安装lxml解析器性能更好 pip install lxml4. 第一个简单爬虫实例4.1 基础网页下载示例import requests # 设置请求头模拟浏览器访问 headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } def download_page(url): 下载网页内容 try: response requests.get(url, headersheaders, timeout10) response.encoding utf-8 # 设置编码 if response.status_code 200: return response.text else: print(f请求失败状态码{response.status_code}) return None except Exception as e: print(f下载出错{e}) return None # 测试下载功能 if __name__ __main__: url http://httpbin.org/get html download_page(url) if html: print(网页下载成功) print(html[:500]) # 打印前500个字符4.2 使用BeautifulSoup解析网页from bs4 import BeautifulSoup import requests def parse_html_demo(): 解析HTML示例 html_doc html headtitle测试页面/title/head body h1主标题/h1 p classcontent第一段内容/p p classcontent第二段内容/p a hrefhttps://example.com链接/a ul li项目1/li li项目2/li /ul /body /html # 创建BeautifulSoup对象 soup BeautifulSoup(html_doc, lxml) # 提取标题 title soup.title.string print(f页面标题{title}) # 提取所有段落 paragraphs soup.find_all(p, class_content) for i, p in enumerate(paragraphs, 1): print(f段落{i}{p.text}) # 提取链接 link soup.find(a) print(f链接地址{link[href]}) # 提取列表项 items soup.select(ul li) for item in items: print(f列表项{item.text}) if __name__ __main__: parse_html_demo()5. 完整爬虫项目架构以下是一个完整的爬虫项目结构包含五大核心组件# 1. URL管理器 class UrlManager: def __init__(self): self.new_urls set() # 待爬取的URL集合 self.old_urls set() # 已爬取的URL集合 def add_new_url(self, url): if url not in self.new_urls and url not in self.old_urls: self.new_urls.add(url) def add_new_urls(self, urls): for url in urls: self.add_new_url(url) def has_new_url(self): return len(self.new_urls) 0 def get_new_url(self): new_url self.new_urls.pop() self.old_urls.add(new_url) return new_url # 2. 网页下载器 class HtmlDownloader: def download(self, url): headers {User-Agent: Mozilla/5.0} try: response requests.get(url, headersheaders, timeout10) if response.status_code 200: return response.text return None except: return None # 3. 网页解析器 class HtmlParser: def parse(self, page_url, html_cont): if page_url is None or html_cont is None: return soup BeautifulSoup(html_cont, lxml) new_urls self._get_new_urls(page_url, soup) new_data self._get_new_data(page_url, soup) return new_urls, new_data def _get_new_urls(self, page_url, soup): # 提取页面中的所有链接 new_urls set() links soup.find_all(a, hrefTrue) for link in links: new_url link[href] # 处理相对路径 if new_url.startswith(/): from urllib.parse import urljoin new_url urljoin(page_url, new_url) new_urls.add(new_url) return new_urls def _get_new_data(self, page_url, soup): # 提取页面中的数据 data {} data[url] page_url data[title] soup.title.string if soup.title else data[content] soup.get_text()[:200] # 取前200个字符 return data # 4. 数据输出器 class DataOutput: def __init__(self): self.datas [] def store_data(self, data): if data: self.datas.append(data) def output_html(self): with open(output.html, w, encodingutf-8) as f: f.write(htmlheadmeta charsetutf-8/headbody) f.write(table border1) f.write(trthURL/thth标题/thth内容摘要/th/tr) for data in self.datas: f.write(tr) f.write(ftd{data[url]}/td) f.write(ftd{data[title]}/td) f.write(ftd{data[content]}/td) f.write(/tr) f.write(/table/body/html) print(f数据已保存到output.html共{len(self.datas)}条记录) # 5. 爬虫调度器主控制器 class SpiderMan: def __init__(self): self.manager UrlManager() self.downloader HtmlDownloader() self.parser HtmlParser() self.output DataOutput() def crawl(self, root_url): # 添加起始URL self.manager.add_new_url(root_url) # 控制爬取数量 count 0 max_count 10 while self.manager.has_new_url() and count max_count: try: # 获取新的URL new_url self.manager.get_new_url() print(f正在爬取第{count1}个URL{new_url}) # 下载网页 html self.downloader.download(new_url) # 解析网页 new_urls, new_data self.parser.parse(new_url, html) # 将新的URL添加到URL管理器 self.manager.add_new_urls(new_urls) # 存储数据 self.output.store_data(new_data) count 1 print(f成功抓取第{count}个页面) except Exception as e: print(f爬取失败{e}) # 输出结果 self.output.output_html() # 主程序 if __name__ __main__: # 使用示例网站请遵守robots.txt root_url http://httpbin.org/html spider SpiderMan() spider.crawl(root_url)6. 进阶技巧与最佳实践6.1 处理动态加载内容使用Selenium# 安装pip install selenium from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def crawl_dynamic_page(): 爬取动态加载的页面 options webdriver.ChromeOptions() options.add_argument(--headless) # 无头模式 driver webdriver.Chrome(optionsoptions) try: driver.get(https://example.com) # 等待元素加载 element WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, content)) ) # 获取页面源码 html driver.page_source soup BeautifulSoup(html, lxml) # 解析数据... finally: driver.quit()6.2 添加延迟和错误处理import time import random from requests.exceptions import RequestException def safe_download(url, retries3): 带重试机制的下载函数 for attempt in range(retries): try: time.sleep(random.uniform(1, 3)) # 随机延迟1-3秒 response requests.get(url, timeout15) response.raise_for_status() return response.text except RequestException as e: print(f第{attempt1}次尝试失败{e}) if attempt retries - 1: return None time.sleep(2 ** attempt) # 指数退避6.3 遵守robots.txtimport urllib.robotparser def check_robots_txt(url): 检查robots.txt协议 rp urllib.robotparser.RobotFileParser() base_url /.join(url.split(/)[:3]) # 获取域名 rp.set_url(base_url /robots.txt) rp.read() if rp.can_fetch(*, url): print(f允许爬取{url}) return True else: print(f禁止爬取{url}) return False7. 实战项目爬取新闻网站以下是一个完整的新闻爬虫示例import requests from bs4 import BeautifulSoup import csv import time class NewsCrawler: def __init__(self): self.headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } def fetch_news(self, url): 抓取新闻页面 try: response requests.get(url, headersself.headers) soup BeautifulSoup(response.text, lxml) # 假设新闻页面结构 news_data { title: soup.find(h1).text.strip() if soup.find(h1) else , author: soup.find(span, class_author).text if soup.find(span, class_author) else 未知, publish_time: soup.find(time)[datetime] if soup.find(time) else , content: .join([p.text for p in soup.find_all(p, class_content)]) } return news_data except Exception as e: print(f抓取失败{e}) return None def save_to_csv(self, data_list, filenamenews.csv): 保存到CSV文件 if not data_list: return keys data_list[0].keys() with open(filename, w, newline, encodingutf-8-sig) as f: writer csv.DictWriter(f, fieldnameskeys) writer.writeheader() writer.writerows(data_list) print(f数据已保存到{filename}) # 使用示例 if __name__ __main__: crawler NewsCrawler() # 示例URL列表实际使用时替换为真实URL news_urls [ http://example.com/news/1, http://example.com/news/2 ] all_news [] for url in news_urls: print(f正在处理{url}) news crawler.fetch_news(url) if news: all_news.append(news) time.sleep(2) # 礼貌性延迟 crawler.save_to_csv(all_news)8. 学习路径建议阶段学习内容预计时间目标第一阶段Python基础语法、PyCharm使用1-2周能编写简单Python程序第二阶段requests、BeautifulSoup基础1周能爬取静态网页数据第三阶段爬虫架构设计、数据存储2周能构建完整爬虫项目第四阶段反爬虫对策、动态页面2周能处理复杂网站第五阶段Scrapy框架、分布式爬虫3周能开发企业级爬虫9. 重要注意事项法律与道德始终遵守网站的robots.txt协议尊重版权和个人隐私频率控制避免对同一网站过快请求添加合理的延迟错误处理完善的异常处理机制确保程序稳定性数据清洗对爬取的数据进行清洗和验证更新维护网站结构变化时及时调整解析逻辑10. 下一步学习建议掌握基础爬虫后建议深入学习Scrapy框架专业的爬虫框架数据库存储MySQL、MongoDB异步爬虫aiohttp、asyncio验证码识别PIL、OpenCV分布式爬虫Redis、Scrapy-Redis通过以上系统学习您将能够从零基础逐步掌握Python网络爬虫开发最终达到精通水平。建议每个阶段都动手实践通过实际项目巩固所学知识。参考来源【愚公系列】《Python网络爬虫从入门到精通》001-初识网络爬虫python爬虫入门教程(一)开始爬虫前的准备工作Python 网络爬虫入门详解PyCharm安装教程(详细步骤)python自学免费教程-怎样自学python编程从零开始学习pythonpython开发入门到精通Python 网络爬虫入门详解
PyCharm配置与爬虫入门指南
Python网络爬虫从零基础到精通教程1. 环境准备与PyCharm 2021配置首先您需要在计算机上安装Python和PyCharm 2021。以下是详细步骤1.1 安装Python访问Python官网https://www.python.org/downloads/下载最新稳定版推荐Python 3.8安装时务必勾选Add Python to PATH选项。1.2 安装PyCharm 2021访问JetBrains官网下载PyCharm 2021 Community版免费运行安装程序按默认设置完成安装首次启动时建议进行以下配置选择深色主题如Darcula保护眼睛安装中文语言包可选设置合适的字体大小推荐14-16px1.3 创建第一个Python项目# 在PyCharm中创建新项目步骤 # 1. File → New Project # 2. 选择项目位置和解释器自动检测已安装的Python # 3. 右键项目 → New → Python File # 4. 输入文件名如first_crawler.py2. 网络爬虫基础概念网络爬虫Web Crawler是一种自动化程序用于从互联网上抓取数据。其主要工作流程如下组件功能描述对应工具/库URL管理器管理待抓取和已抓取的URL队列列表/集合网页下载器下载网页内容requests库网页解析器提取所需数据BeautifulSoup数据存储器保存抓取结果文件/数据库3. 核心库安装与使用在PyCharm的Terminal中执行以下命令安装必要库# 安装requests库用于网页下载 pip install requests # 安装BeautifulSoup4用于网页解析 pip install beautifulsoup4 # 安装lxml解析器性能更好 pip install lxml4. 第一个简单爬虫实例4.1 基础网页下载示例import requests # 设置请求头模拟浏览器访问 headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } def download_page(url): 下载网页内容 try: response requests.get(url, headersheaders, timeout10) response.encoding utf-8 # 设置编码 if response.status_code 200: return response.text else: print(f请求失败状态码{response.status_code}) return None except Exception as e: print(f下载出错{e}) return None # 测试下载功能 if __name__ __main__: url http://httpbin.org/get html download_page(url) if html: print(网页下载成功) print(html[:500]) # 打印前500个字符4.2 使用BeautifulSoup解析网页from bs4 import BeautifulSoup import requests def parse_html_demo(): 解析HTML示例 html_doc html headtitle测试页面/title/head body h1主标题/h1 p classcontent第一段内容/p p classcontent第二段内容/p a hrefhttps://example.com链接/a ul li项目1/li li项目2/li /ul /body /html # 创建BeautifulSoup对象 soup BeautifulSoup(html_doc, lxml) # 提取标题 title soup.title.string print(f页面标题{title}) # 提取所有段落 paragraphs soup.find_all(p, class_content) for i, p in enumerate(paragraphs, 1): print(f段落{i}{p.text}) # 提取链接 link soup.find(a) print(f链接地址{link[href]}) # 提取列表项 items soup.select(ul li) for item in items: print(f列表项{item.text}) if __name__ __main__: parse_html_demo()5. 完整爬虫项目架构以下是一个完整的爬虫项目结构包含五大核心组件# 1. URL管理器 class UrlManager: def __init__(self): self.new_urls set() # 待爬取的URL集合 self.old_urls set() # 已爬取的URL集合 def add_new_url(self, url): if url not in self.new_urls and url not in self.old_urls: self.new_urls.add(url) def add_new_urls(self, urls): for url in urls: self.add_new_url(url) def has_new_url(self): return len(self.new_urls) 0 def get_new_url(self): new_url self.new_urls.pop() self.old_urls.add(new_url) return new_url # 2. 网页下载器 class HtmlDownloader: def download(self, url): headers {User-Agent: Mozilla/5.0} try: response requests.get(url, headersheaders, timeout10) if response.status_code 200: return response.text return None except: return None # 3. 网页解析器 class HtmlParser: def parse(self, page_url, html_cont): if page_url is None or html_cont is None: return soup BeautifulSoup(html_cont, lxml) new_urls self._get_new_urls(page_url, soup) new_data self._get_new_data(page_url, soup) return new_urls, new_data def _get_new_urls(self, page_url, soup): # 提取页面中的所有链接 new_urls set() links soup.find_all(a, hrefTrue) for link in links: new_url link[href] # 处理相对路径 if new_url.startswith(/): from urllib.parse import urljoin new_url urljoin(page_url, new_url) new_urls.add(new_url) return new_urls def _get_new_data(self, page_url, soup): # 提取页面中的数据 data {} data[url] page_url data[title] soup.title.string if soup.title else data[content] soup.get_text()[:200] # 取前200个字符 return data # 4. 数据输出器 class DataOutput: def __init__(self): self.datas [] def store_data(self, data): if data: self.datas.append(data) def output_html(self): with open(output.html, w, encodingutf-8) as f: f.write(htmlheadmeta charsetutf-8/headbody) f.write(table border1) f.write(trthURL/thth标题/thth内容摘要/th/tr) for data in self.datas: f.write(tr) f.write(ftd{data[url]}/td) f.write(ftd{data[title]}/td) f.write(ftd{data[content]}/td) f.write(/tr) f.write(/table/body/html) print(f数据已保存到output.html共{len(self.datas)}条记录) # 5. 爬虫调度器主控制器 class SpiderMan: def __init__(self): self.manager UrlManager() self.downloader HtmlDownloader() self.parser HtmlParser() self.output DataOutput() def crawl(self, root_url): # 添加起始URL self.manager.add_new_url(root_url) # 控制爬取数量 count 0 max_count 10 while self.manager.has_new_url() and count max_count: try: # 获取新的URL new_url self.manager.get_new_url() print(f正在爬取第{count1}个URL{new_url}) # 下载网页 html self.downloader.download(new_url) # 解析网页 new_urls, new_data self.parser.parse(new_url, html) # 将新的URL添加到URL管理器 self.manager.add_new_urls(new_urls) # 存储数据 self.output.store_data(new_data) count 1 print(f成功抓取第{count}个页面) except Exception as e: print(f爬取失败{e}) # 输出结果 self.output.output_html() # 主程序 if __name__ __main__: # 使用示例网站请遵守robots.txt root_url http://httpbin.org/html spider SpiderMan() spider.crawl(root_url)6. 进阶技巧与最佳实践6.1 处理动态加载内容使用Selenium# 安装pip install selenium from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC def crawl_dynamic_page(): 爬取动态加载的页面 options webdriver.ChromeOptions() options.add_argument(--headless) # 无头模式 driver webdriver.Chrome(optionsoptions) try: driver.get(https://example.com) # 等待元素加载 element WebDriverWait(driver, 10).until( EC.presence_of_element_located((By.CLASS_NAME, content)) ) # 获取页面源码 html driver.page_source soup BeautifulSoup(html, lxml) # 解析数据... finally: driver.quit()6.2 添加延迟和错误处理import time import random from requests.exceptions import RequestException def safe_download(url, retries3): 带重试机制的下载函数 for attempt in range(retries): try: time.sleep(random.uniform(1, 3)) # 随机延迟1-3秒 response requests.get(url, timeout15) response.raise_for_status() return response.text except RequestException as e: print(f第{attempt1}次尝试失败{e}) if attempt retries - 1: return None time.sleep(2 ** attempt) # 指数退避6.3 遵守robots.txtimport urllib.robotparser def check_robots_txt(url): 检查robots.txt协议 rp urllib.robotparser.RobotFileParser() base_url /.join(url.split(/)[:3]) # 获取域名 rp.set_url(base_url /robots.txt) rp.read() if rp.can_fetch(*, url): print(f允许爬取{url}) return True else: print(f禁止爬取{url}) return False7. 实战项目爬取新闻网站以下是一个完整的新闻爬虫示例import requests from bs4 import BeautifulSoup import csv import time class NewsCrawler: def __init__(self): self.headers { User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 } def fetch_news(self, url): 抓取新闻页面 try: response requests.get(url, headersself.headers) soup BeautifulSoup(response.text, lxml) # 假设新闻页面结构 news_data { title: soup.find(h1).text.strip() if soup.find(h1) else , author: soup.find(span, class_author).text if soup.find(span, class_author) else 未知, publish_time: soup.find(time)[datetime] if soup.find(time) else , content: .join([p.text for p in soup.find_all(p, class_content)]) } return news_data except Exception as e: print(f抓取失败{e}) return None def save_to_csv(self, data_list, filenamenews.csv): 保存到CSV文件 if not data_list: return keys data_list[0].keys() with open(filename, w, newline, encodingutf-8-sig) as f: writer csv.DictWriter(f, fieldnameskeys) writer.writeheader() writer.writerows(data_list) print(f数据已保存到{filename}) # 使用示例 if __name__ __main__: crawler NewsCrawler() # 示例URL列表实际使用时替换为真实URL news_urls [ http://example.com/news/1, http://example.com/news/2 ] all_news [] for url in news_urls: print(f正在处理{url}) news crawler.fetch_news(url) if news: all_news.append(news) time.sleep(2) # 礼貌性延迟 crawler.save_to_csv(all_news)8. 学习路径建议阶段学习内容预计时间目标第一阶段Python基础语法、PyCharm使用1-2周能编写简单Python程序第二阶段requests、BeautifulSoup基础1周能爬取静态网页数据第三阶段爬虫架构设计、数据存储2周能构建完整爬虫项目第四阶段反爬虫对策、动态页面2周能处理复杂网站第五阶段Scrapy框架、分布式爬虫3周能开发企业级爬虫9. 重要注意事项法律与道德始终遵守网站的robots.txt协议尊重版权和个人隐私频率控制避免对同一网站过快请求添加合理的延迟错误处理完善的异常处理机制确保程序稳定性数据清洗对爬取的数据进行清洗和验证更新维护网站结构变化时及时调整解析逻辑10. 下一步学习建议掌握基础爬虫后建议深入学习Scrapy框架专业的爬虫框架数据库存储MySQL、MongoDB异步爬虫aiohttp、asyncio验证码识别PIL、OpenCV分布式爬虫Redis、Scrapy-Redis通过以上系统学习您将能够从零基础逐步掌握Python网络爬虫开发最终达到精通水平。建议每个阶段都动手实践通过实际项目巩固所学知识。参考来源【愚公系列】《Python网络爬虫从入门到精通》001-初识网络爬虫python爬虫入门教程(一)开始爬虫前的准备工作Python 网络爬虫入门详解PyCharm安装教程(详细步骤)python自学免费教程-怎样自学python编程从零开始学习pythonpython开发入门到精通Python 网络爬虫入门详解