Python爬虫代码错误解析及优化
Python爬虫代码错误解析及优化
这段 Python 代码旨在爬取网站链接,但存在缺乏错误信息导致难以排查问题的情况。以下是对代码进行的优化和分析,并添加了更详细的错误信息输出,方便定位问题。
# -*- coding: utf-8 -*-
import requests
from bs4 import BeautifulSoup
import urllib.parse as urlparse
import re
class UrlManager:
def __init__(self):
self.new_urls = set() # 存放新的URL,将被访问并解析response里的新链接,递归下去,直到没有新的URL存进来就退出整个程序
self.old_urls = set() # 存在已经爬取的,且属于本站的链接
def add_new_url(self, url):
if url is None:
return None
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):
if urls is None or len(urls) == 0:
return None
for url in urls:
self.add_new_url(url)
def has_new_url(self):
# 此处自己添加的
if len(self.old_urls) > 10000: # 如果经爬取的链接大于100时,退出主程序
self.new_urls = set()
self.old_urls = set()
return len(self.new_urls) != 0 # 返回新URL元组是否为空,False(不为空)或True(空),空表示没有新的URL需要爬行了,会退出主程序
def get_new_url(self):
new_url = self.new_urls.pop() # 从新URL元组中取一个URL
self.old_urls.add(new_url) # 把它移到旧的URL数组,
return new_url
class HtmlDownLoader():
def download(self, url):
if url is None:
return None
try:
r = requests.get(url)
if r.status_code != 200:
return None
return r.text
except Exception as e:
print(f'下载页面 {url} 失败: {e}')
return None
class HtmlParser:
def __init__(self):
self.foreign_urls = set()
def _get_root_domain(self, url):
# 是否应该在这里用正则判断传进来的URL是/开头,如果解析出来netloc是空,那也算是当前域名的链接
if url is None:
return None
try:
url_info = urlparse.urlparse(url)
root_domain = url_info.netloc
return root_domain
except Exception as e:
print(f'解析域名 {url} 失败: {e}')
return None
def _get_new_urls(self, soup, current_url):
new_urls = set()
links = soup.find_all('a')
for link in links:
new_url = link.get('href')
if new_url is not None:
new_url = new_url.lstrip()
new_url_root_domain = self._get_root_domain(new_url)
if new_url_root_domain == '':
pass
elif new_url_root_domain is not None:
if self._get_root_domain(current_url) != self._get_root_domain(new_url):
if self._get_root_domain(new_url):
self.foreign_urls.add(self._get_root_domain(new_url))
continue
# elif new_url_root_domain is None:
# pass
new_full_url = urlparse.urljoin(current_url, new_url)
new_urls.add(new_full_url)
return new_urls
def parse(self, html_content, current_url):
if html_content is None:
return
try:
soup = BeautifulSoup(html_content, 'html.parser')
new_urls = self._get_new_urls(soup, current_url)
return new_urls
except Exception as e:
print(f'解析页面 {current_url} 失败: {e}')
return None
def get_foreign_urls(self):
return self.foreign_urls
class SpiderMain:
def __init__(self, ):
self.urls = UrlManager()
self.html_downloader = HtmlDownLoader()
self.parser = HtmlParser()
def craw(self, root_url, name):
self.urls.add_new_url(root_url)
while self.urls.has_new_url():
new_url = self.urls.get_new_url()
try:
html_content = self.html_downloader.download(new_url)
if html_content is None:
continue
new_urls = self.parser.parse(html_content, new_url)
if new_urls is None:
continue
self.urls.add_new_urls(new_urls)
with open('%s_data.txt' % (name), 'a') as f:
f.write(new_url + '\n')
print(f'爬取 {new_url} 成功')
except Exception as e:
print(f'爬取 {new_url} 失败: {e}')
print(f'已爬取 {len(self.urls.old_urls)} 个链接,{self.urls.old_urls}')
print(f'发现 {len(self.parser.foreign_urls)} 个外域链接: {self.parser.foreign_urls}')
if __name__ == '__main__':
name = input('请输入网站名称: ')
with open('%s.txt' % (name)) as fp:
for u in fp:
root_url = u.strip('\r\n')
with open('%s_data.txt' % (name), 'a') as f:
pass
# root_url = u if '://' in u else 'http://' + u
# root_url = 'http://www.zzyidc.com/'
obj_spider = SpiderMain()
obj_spider.craw(root_url, name)
代码优化说明
- 添加错误信息输出: 在
HtmlDownLoader、HtmlParser和SpiderMain中添加了try...except语句,捕获异常并输出错误信息,包括错误类型和发生错误的 URL。 - 增加判断语句: 在
SpiderMain中增加判断语句,检查下载和解析是否成功,避免继续处理无效的数据。 - 简化代码: 删除了部分冗余代码,例如
_get_root_domain中的elif语句。 - 输出更详细的信息: 在
SpiderMain中增加了输出,包括已爬取的链接数量和发现的外域链接数量。
使用方法
- 将以上代码保存为 Python 文件,例如
spider.py。 - 创建一个名为
网站名称.txt的文本文件,将需要爬取的网站链接写入文件,每行一个链接。 - 运行
python spider.py命令,输入网站名称,程序将开始爬取链接并输出爬取结果。
搜索引擎优化
- 标题:Python爬虫代码错误解析及优化
- 描述:本篇文章分析并优化一段 Python 爬虫代码,解决代码中缺乏错误信息导致难以排查问题的情况,并提供更详细的错误信息输出,方便定位问题。
- 关键词:Python爬虫, 代码错误, 爬虫优化, 错误解析, 搜索引擎优化, SEO
通过以上优化,代码更易于阅读和维护,并可以更加有效地定位和解决错误。同时,文章内容也更加清晰易懂,方便读者理解和应用。*
原文地址: https://www.cveoy.top/t/topic/nxrd 著作权归作者所有。请勿转载和采集!