使用BeautifulSoup爬取“0daydown”网站的信息(2)——字符编码问题解决

上篇中的程序实现了抓取0daydown最新的10页信息,输出是直接输出到控制台里面。再次改进代码时我准备把它们写入到一个TXT文档中。这是问题就出来了。

最初我的代码如下:

#-*- coding: utf-8 -*-
#-------------------------------------
#version: 0.1
#note:实现了查找0daydown最新发布的10页资源。
#-------------------------------------
#-------------------------------------
#version: 0.2
#note:在v0.1基础上输出内容到一个指定TXT文件中
#-------------------------------------

import urllib.request
import sys
import locale

from bs4 import BeautifulSoup

print(locale.getdefaultlocale())

old = sys.stdout        #保存系统默认输出
fp = open("test1.txt",'w')
#fp = open("test1.txt",'w', encoding="utf-8")    #以utf-8进行文件编码
sys.stdout = fp         #输出重定向到一个文件中

for i in range(1,11):
	url = "http://www.0daydown.com/page/" + str(i)	#每一页的Url只需在后面加上整数就行
	page = urllib.request.urlopen(url)
	soup_packtpage = BeautifulSoup(page)
	page.close()
	num = " The Page of: " + str(i)		#标注当前资源属于第几页
	print(num)
	print("#"*40)
	for article in soup_packtpage.find_all('article', class_="excerpt"):	#使用find_all查找出当前页面发布的所有最新资源
		print("Category:".ljust(20), end=''), print(article.header.a.next)   #category
		print("Title:".ljust(20), end=''), print(article.h2.string)       #title
		print("Pulished_time:".ljust(19), end=''), print(article.p.find('i', class_="icon-time icon12").next)  #published_time
		print("Note:", end='')
		print(article.p.find_next_sibling().string)    #note
		print('-'*50)

fp.close()
sys.stdout = old    #恢复系统默认输出
print("Done!")
input() #等待输入,为了不让控制台运行后立即结束。

运行文件后报错:错误信息如下:

Traceback (most recent call last):
  File "E:\codefile\Soup\0daydown - 0.2.py", line 37, in <module>
    print(article.p.find_next_sibling().string)    #note
UnicodeEncodeError: 'gbk' codec can't encode character '\xa0' in position 117: illegal multibyte sequence

从文中可以看出是Unicode编码错误,说gbk不能编码\xa0这个字节。就字符编码这个问题我看了好多文章,查阅了好多资料。新手没办法,不过还好弄懂了。

最初的时候我根本毫无头绪,查看网上的一些文章开始模仿进行encode.decode的,根本没有用,输出仍然有问题,不抛出异常了,但是根本看不到汉字了,全是一些\x..这种替代了。

问题要追根朔源,我连基本的字符编码和字符集这些东西都没有搞清楚,怎么能解决问题呢?于是我搜索这方面相关文章,给出我觉得好的文章的链接如下:

字符编码详解   这篇文章虽然长,但是作者总结的太详细了,看了后收获很大。

于是我想为什么写入到文件中就会报错呢?而命令行输出就没有这个问题。难道文件有问题?文件的编码有问题?我顺着这个问题找到了一篇讲Python3的文件的文章,很好,链接如下:

Python3的文件  其中里面写到了文件的编码,原来打开文件时是可以指定文件编码的,如果不指定,那么文件默认采用什么编码方式呢?这篇文章做出了详细的解释。

我的源代码中打开文件的方式是:fp = open("test1.txt",‘w‘),结果抛出异常,从上面抛出的异常可以说明默认打开文件,文件的编码方式是gbk,而GBK是不能编码\xa0这个字符的,查了下这个字符,原来是HTML中特有的空字符&nbsp。要爬取的网页默认的编码方式是utf-8,说明utf-8是能编码这个字符的。那么我们可以指定文件的编码方式不呢?答案是可以,原来open中还有个参数是encoding,用来指定编码方式,如果我们指定它为utf-8会怎样?下面是正确的代码,不同的只是把fp
= open("test1.txt",‘w‘)变为了fp = open("test1.txt",‘w‘, encoding="utf-8")。代码如下:

#-*- coding: utf-8 -*-
#-------------------------------------
#version: 0.1
#note:实现了查找0daydown最新发布的10页资源。
#-------------------------------------
#-------------------------------------
#version: 0.2
#note:在v0.1基础上输出内容到一个指定TXT文件中
#-------------------------------------

import urllib.request
import sys

from bs4 import BeautifulSoup

old = sys.stdout        #保存系统默认输出
#fp = open("test1.txt",'w')
fp = open("test1.txt",'w', encoding="utf-8")    #以utf-8进行文件编码
sys.stdout = fp         #输出重定向到一个文件中

for i in range(1,11):
	url = "http://www.0daydown.com/page/" + str(i)	#每一页的Url只需在后面加上整数就行
	page = urllib.request.urlopen(url)
	soup_packtpage = BeautifulSoup(page)
	page.close()
	num = " The Page of: " + str(i)		#标注当前资源属于第几页
	print(num)
	print("#"*40)
	for article in soup_packtpage.find_all('article', class_="excerpt"):	#使用find_all查找出当前页面发布的所有最新资源
		print("Category:".ljust(20), end=''), print(article.header.a.next)   #category
		print("Title:".ljust(20), end=''), print(article.h2.string)       #title
		print("Pulished_time:".ljust(19), end=''), print(article.p.find('i', class_="icon-time icon12").next)  #published_time
		print("Note:", end='')
		print(article.p.find_next_sibling().string)    #note
		print('-'*50)

fp.close()
sys.stdout = old    #恢复系统默认输出
print("Done!")
input() #等待输入,为了不让控制台运行后立即结束。

运行后,无错误产生,成功写入文件,打开文件,显示如下:

可以看出,输出结果与上一篇命令行输出的结果是一样的。圆满解决,OK!!另外,今天抽空学了下Github,早闻大名,看了下介绍,发现很强大,跟着官网教程Helloworld入了下门,注册了个帐号,准备以后代码都放在那上面了。

时间: 2024-10-04 17:54:25

使用BeautifulSoup爬取“0daydown”网站的信息(2)——字符编码问题解决的相关文章

使用BeautifulSoup爬取“0daydown”站点的信息(2)——字符编码问题解决

上篇中的程序实现了抓取0daydown最新的10页信息.输出是直接输出到控制台里面.再次改进代码时我准备把它们写入到一个TXT文档中.这是问题就出来了. 最初我的代码例如以下: #-*- coding: utf-8 -*- #------------------------------------- #version: 0.1 #note:实现了查找0daydown最新公布的10页资源. #------------------------------------- #--------------

Python 利用 BeautifulSoup 爬取网站获取新闻流

0. 引言 介绍下 Python 用 Beautiful Soup 周期性爬取 xxx 网站获取新闻流: 图 1 项目介绍 1. 开发环境 Python: 3.6.3 BeautifulSoup:   4.2.0 , 是一个可以从HTML或XML文件中提取数据的Python库* ( BeautifulSoup 的中文官方文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/ ) 2. 代码介绍 实现主要分为三个模块: 1. 计时

[python爬虫] BeautifulSoup和Selenium对比爬取豆瓣Top250电影信息

这篇文章主要对比BeautifulSoup和Selenium爬取豆瓣Top250电影信息,两种方法从本质上都是一样的,都是通过分析网页的DOM树结构进行元素定位,再定向爬取具体的电影信息,通过代码的对比,你可以进一步加深Python爬虫的印象.同时,文章给出了我以前关于爬虫的基础知识介绍,方便新手进行学习.        总之,希望文章对你有所帮助,如果存在不错或者错误的地方,还请海涵~ 一. DOM树结构分析 豆瓣Top250电影网址:https://movie.douban.com/top2

python 爬取淘宝模特信息

通过本篇博文,介绍一下我对指定信息进行爬取的时候的思路,顺便贴一下代码. 一.首先获取想要爬取的网站的url链接的规则变化 可以看出来该网站页面的url结构简单,变化的只是https://mm.taobao.com/json/request_top_list.htm?page= page的值 二.对网站页面的DOM树的结构进行分析,方便我们获取我们想要的内容信息, 我写了个简单的网页分析脚本analyze.py:用来输出DOM树,方便我后面做筛选. # -*- coding:utf-8 -*-

[Python爬虫] Selenium爬取新浪微博客户端用户信息、热点话题及评论 (上)

一. 文章介绍 前一篇文章"[python爬虫] Selenium爬取新浪微博内容及用户信息"简单讲述了如何爬取新浪微博手机端用户信息和微博信息. 用户信息:包括用户ID.用户名.微博数.粉丝数.关注数等. 微博信息:包括转发或原创.点赞数.转发数.评论数.发布时间.微博内容等. 它主要通过从文本txt中读取用户id,通过"URL+用户ID" 访问个人网站,如柳岩: http://weibo.cn/guangxianliuya 因为手机端数据相对精简简单,所以采用输

python爬虫--爬取某网站电影下载地址

前言:因为自己还是python世界的一名小学生,还有很多路要走,所以本文以目的为向导,达到目的即可,对于那些我自己都没弄懂的原理,不做去做过多解释,以免误人子弟,大家可以网上搜索. 友情提示:本代码用到的网址仅供交流学习使用,如有不妥,请联系删除. 背景:自己有台电脑要给老爸用,老爷子喜欢看一些大片,但是家里网络环境不好,就想批量下载一些存到电脑里.但是目前大部分的网站都是这样的, 需要一个个地点进去,才能看到下载地址 如果我要下载100部电影,那肯定手都要点断了,于是便想把这些地址给爬取出来,

利用Selenium爬取淘宝商品信息

一.  Selenium和PhantomJS介绍 Selenium是一个用于Web应用程序测试的工具,Selenium直接运行在浏览器中,就像真正的用户在操作一样.由于这个性质,Selenium也是一个强大的网络数据采集工具,其可以让浏览器自动加载页面,这样,使用了异步加载技术的网页,也可获取其需要的数据. Selenium模块是Python的第三方库,可以通过pip进行安装: pip3 install selenium Selenium自己不带浏览器,需要配合第三方浏览器来使用.通过help命

Node.js爬虫-爬取慕课网课程信息

第一次学习Node.js爬虫,所以这时一个简单的爬虫,Node.js的好处就是可以并发的执行 这个爬虫主要就是获取慕课网的课程信息,并把获得的信息存储到一个文件中,其中要用到cheerio库,它可以让我们方便的操作HTML,就像是用jQ一样 开始前,记得 npm install cheerio 为了能够并发的进行爬取,用到了Promise对象 //接受一个url爬取整个网页,返回一个Promise对象 function getPageAsync(url){ return new Promise(

python爬取某个网站的图片并保存到本地

python爬取某个网站的图片并保存到本地 #coding:utf-8 import urllib import re import sys reload(sys) sys.setdefaultencoding('gb2312') #获取整个页面的数据 def getHtml (url): page = urllib.urlopen(url) html = page.read() return html #保存图片到本地 def getImg(html): reg = r'src="(.+?\.