第一个python网络爬虫总结

简介:
这个程序其实就是模仿用户的网页访问操作。 
先从主页上获取大的商品分类,再一级一级地遍历所有的小分类。在最后得到商品列表,再遍历每个商品页,从商品页是抓取有效的信息。 

这里,我对一些关键点做个总结,以便以后用到好回顾。 

一,怎么访问网页?


# 根据url获取网页正文
def get_webpage(url):
    headers = {\
            'User-Agent' : 'Mozilla/5.0 (X11; Linux i686; rv:34.0) Gecko/20100101 Firefox/34.0',\
            'Accept'     : 'text/html',\
            'Connection' : 'keep-alive'}
    try:
        request = urllib2.Request(url, None, headers)
        response = urllib2.urlopen(request, timeout=120)
        webpage = response.read()
        response.close()
        return webpage
 
    #except urllib2.HTTPError, e:
    #    print('HTTPError: ' + str(e.code))
    #except urllib2.URLError, e:
    #    print('URLError: ' + str(e.reason))
    except Exception, e:
        print('发生异常: ' + str(e))

  上面这个函数就是用uillib2.urlopen()函数获取url网址的网页内容。也可以不用urllib2.Request(),直接用urllib2.urlopen()。这么做为是为了仿造正常的浏览器的访问操作。 

二,数据保存 
  数据最好保存为xls文件格式,如果没有办法保存为csw文本格式也可以,也可以保存为txt文本格式。 
  最好做成根据用户输入的文件名的后缀名进行自动识别。 

  (1)先分别定义函数 save_as_csw(), save_as_txt(), save_as_xls() 实现csw,txt,xls文件格式的保存。 


def save_as_csw(prod_list, filename):
    if len(prod_list) == 0:
        return False
 
    #分类 商品 价格 联系人 手机 公司 座机 传真 地址 公司网址 源自网页 
    line_fmt = '"%s"\t"%s"\t"%s"\t"%s"\t"%s"\t"%s"\t"%s"\t"%s"\t"%s"\t"%s"\t"%s"\n'
    lines = []
    head_line = line_fmt % ('分类', '商品', '价格', '联系人', '手机号','公司', 
                            '电话', '传真', '公司地址', '公司网址', '源网页')
    lines.append(head_line)
    for item in prod_list:
        info = item['detail']
        if info == None:    #如果信息不全,则跳过
            continue
 
        prod_line = line_fmt % (item['path'], info['name'], info['price'],\
                                info['contact'], info['cell-phone'], info['company'], \
                                info['tel-phone'], info['fax'], info['address'], info['website'], item['url'])
        lines.append(prod_line)
     
    wfile = open(filename, 'w')
    wfile.writelines(lines)
    wfile.close()
    return True
 
def save_as_txt(prod_list, filename):
    if len(prod_list) == 0:
        return False
 
    #分类 商品 价格 联系人 手机 公司 座机 传真 地址 公司网址 源自网页 
    line_fmt = '%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\n'
    lines = []
    head_line = line_fmt % ('分类', '商品', '价格', '联系人', '手机号','公司', 
                            '电话', '传真', '公司地址', '公司网址', '源网页')
    lines.append(head_line)
    for item in prod_list:
        info = item['detail']
        if info == None:    #如果信息不全,则跳过
            continue
 
        prod_line = line_fmt % (item['path'], info['name'], info['price'],\
                                info['contact'], info['cell-phone'], info['company'], \
                                info['tel-phone'], info['fax'], info['address'], info['website'], item['url'])
        lines.append(prod_line)
     
    wfile = open(filename, 'w')
    wfile.writelines(lines)
    wfile.close()
    return True
 
#保存数据到xls文件中,每个大类放在不同的Worksheet中
def save_as_xls(prod_list, filename):
    if len(prod_list) == 0:
        return False
 
    workbook = xlwt.Workbook(encoding='utf-8')  #必须注明编码格式,否则会保存失败
    curr_category = ''
    worksheet = None
    row_index = 0
    for prod_item in prod_list:
        path = prod_item['path']
        this_category = path.split('/')[0]
        #如果当前的这个商品种类与上一个商品不同,则要新建worksheet
        if this_category != curr_category:
            worksheet = workbook.add_sheet(this_category)
            curr_category = this_category
            #填写表头
            header_cells = ('分类', '商品', '价格', '联系人', '手机号','公司', 
                     '电话', '传真', '公司地址', '公司网址', '源网页')
 
            column_index = 0
            for cell in header_cells:
                worksheet.write(0, column_index, header_cells[column_index])
                column_index += 1
            #创建了新了worksheet后,数据从第二行开始往下写
            row_index = 1 
 
        #将数据填写到worksheet的row_index行
        prod_info = prod_item['detail']
        #如果信息不全,则跳过
        if prod_info == None:
            continue
 
        prod_cells = (path, prod_info['name'], prod_info['price'], prod_info['contact'],\
                 prod_info['cell-phone'], prod_info['company'], prod_info['tel-phone'],\
                 prod_info['fax'], prod_info['address'], prod_info['website'], prod_item['url'])
 
        column_index = 0
        for cell in prod_cells:
            worksheet.write(row_index, column_index, prod_cells[column_index])
            column_index += 1
 
        row_index += 1
        pass
    workbook.save(filename)
    return True

  (2)定义DataSaver类,实现统一的文件保存功能。并用 case_dict 根据后缀名进行分别保存。


def get_filename_postfix(filename):
    basename = os.path.basename(filename)
    temp = basename.split('.')
    if len(temp) >= 2:
        return temp[-1]
 
class DataSaver:
    #后缀名与保存函数映射表
    case_dict = {'csw':save_as_csw,\
                 'txt':save_as_txt}
    if xlwt_enabled:
        case_dict['xls'] = save_as_xls
 
    #将商品列表数据‘喂’给DataSaver
    def feed(self, data):
        self.product_list = data
        pass
 
    def save_as(self, filename):
        if self.product_list == None or len(self.product_list) == 0:
            print('警告:记录为空,不保存')
            return
 
        print('正在保存……')
        while True:
            postfix = get_filename_postfix(filename)
            try:
                if self.case_dict[postfix](self.product_list, filename):
                    print('已保存到:' + filename)
                else:
                    print('保存失败!')
                break
            except KeyError:
                print('警告:不支持 %s 文件格式。' % (postfix))
                print('支持的文件格式:' + ','.join(self.case_dict.keys()))
                try:
                    filename = raw_input('请输入新文件名:')
                except KeyboardInterrupt:
                    print('用户取消保存')
                    break
        pass
    pass

  (3)如果没有安装 xlwt ,就不能支持 xls 文件的保存。 
  这里的做法是:如果import xlwt成功,则将xls文件的保存函数添加到case_dict中。 
  如果文件格式不支持,就提示让用户另命个文件名进行保存。 


#如果没有安装xlwt,那么保存为xls文件就不可用
xlwt_enabled = True
try:
    import xlwt
except ImportError: 
    xlwt_enabled = False

 见 DataSaver.save_as() 函数中对 xls 后缀名的处理。

三,遇到的问题与解决方法

(1)python程序里不能有中文的问题。
  以前,只有python程序里有中文,不管是在哪儿,都不能运行。原来是python解析器默认将文件识别为ascii编码格式的,有中文当然就不误别。解决这问题的办法是:明确告知解析器我们文件的编码格式。


#!/usr/bin/env python
#-*- coding=utf-8 -*-

  这样就可以了。

(2)安装xlwt3不成功的问题。
  从网上下载xlwt3进行安装。python setup.py install 失败,报print()函数不支持print("xxxx", file=f)这种格式。我看了一下,这个功能python 2.6是没有的。于是重新下载了xlwt-0.7.5.tar.gz进行安装。结果就可以了。

(3)在Windows为乱码的问题。
  这个问题,我还没有解决。


目录
相关文章
|
12天前
|
数据采集 存储 API
网络爬虫与数据采集:使用Python自动化获取网页数据
【4月更文挑战第12天】本文介绍了Python网络爬虫的基础知识,包括网络爬虫概念(请求网页、解析、存储数据和处理异常)和Python常用的爬虫库requests(发送HTTP请求)与BeautifulSoup(解析HTML)。通过基本流程示例展示了如何导入库、发送请求、解析网页、提取数据、存储数据及处理异常。还提到了Python爬虫的实际应用,如获取新闻数据和商品信息。
|
13天前
|
安全 Java 数据处理
Python网络编程基础(Socket编程)多线程/多进程服务器编程
【4月更文挑战第11天】在网络编程中,随着客户端数量的增加,服务器的处理能力成为了一个重要的考量因素。为了处理多个客户端的并发请求,我们通常需要采用多线程或多进程的方式。在本章中,我们将探讨多线程/多进程服务器编程的概念,并通过一个多线程服务器的示例来演示其实现。
|
13天前
|
程序员 开发者 Python
Python网络编程基础(Socket编程) 错误处理和异常处理的最佳实践
【4月更文挑战第11天】在网络编程中,错误处理和异常管理不仅是为了程序的健壮性,也是为了提供清晰的用户反馈以及优雅的故障恢复。在前面的章节中,我们讨论了如何使用`try-except`语句来处理网络错误。现在,我们将深入探讨错误处理和异常处理的最佳实践。
|
16天前
|
数据采集 Python
【python】爬虫-西安医学院-校长信箱
本文以西安医学院-校长信箱为基础来展示爬虫案例。来介绍python爬虫。
【python】爬虫-西安医学院-校长信箱
|
1天前
|
机器学习/深度学习 算法 Python
Python用RNN神经网络:LSTM、GRU、回归和ARIMA对COVID19新冠疫情人数时间序列预测
Python用RNN神经网络:LSTM、GRU、回归和ARIMA对COVID19新冠疫情人数时间序列预测
28 12
|
1天前
|
机器学习/深度学习 算法 算法框架/工具
数据分享|PYTHON用KERAS的LSTM神经网络进行时间序列预测天然气价格例子
数据分享|PYTHON用KERAS的LSTM神经网络进行时间序列预测天然气价格例子
15 0
|
2天前
|
数据采集 存储 JSON
Python爬虫面试:requests、BeautifulSoup与Scrapy详解
【4月更文挑战第19天】本文聚焦于Python爬虫面试中的核心库——requests、BeautifulSoup和Scrapy。讲解了它们的常见问题、易错点及应对策略。对于requests,强调了异常处理、代理设置和请求重试;BeautifulSoup部分提到选择器使用、动态内容处理和解析效率优化;而Scrapy则关注项目架构、数据存储和分布式爬虫。通过实例代码,帮助读者深化理解并提升面试表现。
11 0
|
5天前
|
数据采集 JavaScript 前端开发
使用Python打造爬虫程序之破茧而出:Python爬虫遭遇反爬虫机制及应对策略
【4月更文挑战第19天】本文探讨了Python爬虫应对反爬虫机制的策略。常见的反爬虫机制包括User-Agent检测、IP限制、动态加载内容、验证码验证和Cookie跟踪。应对策略包括设置合理User-Agent、使用代理IP、处理动态加载内容、验证码识别及维护Cookie。此外,还提到高级策略如降低请求频率、模拟人类行为、分布式爬虫和学习网站规则。开发者需不断学习新策略,同时遵守规则和法律法规,确保爬虫的稳定性和合法性。
|
6天前
|
机器学习/深度学习 Python
Python用LSTM长短期记忆神经网络对不稳定降雨量时间序列进行预测分析
Python用LSTM长短期记忆神经网络对不稳定降雨量时间序列进行预测分析
16 0
|
6天前
|
JSON 网络协议 API
Python网络编程面试题精讲
【4月更文挑战第15天】本文介绍了Python网络编程的面试重点,包括基础Socket编程、HTTP协议与requests库、异步编程与asyncio库。通过实例解析常见面试题,强调了非阻塞套接字、异常处理、HTTP状态码检查以及异步任务管理等关键点。提供代码示例帮助读者巩固概念,助力面试准备。
13 0