今天在学习《集体智慧编程》这本书中第四章的搜索与排名时,自己动手尝试将书中Python2编写的实例程序改写成Python3的版本,编写好第一个爬虫程序,代码如下:
#从一个小网页开始进行广度优先搜索,直至某一给定深度
#期间为网页建立索引
def crawl(self,pages,depth=2):
print('searching %s'% pages)
for i in range(depth):
newpages=set()
for page in pages:
try:
c=urllib.request.urlopen(page)
except:
print("Could not open %s "%page)
continue
try:
soup=BeautifulSoup(c.read(),'html.parser')
self.addtoindex(page,soup)
links=soup.find_all('a')
for link in links:
if('href' in link.attrs):
url=urljoin(page,link['href'])
if url.find("'")!=-1:
continue
url=url.split('#')[0] #去掉位置部分
if url[0:4]=='http' and not self.isindexed(url):
newpages.add(url)
print('the link is %s'%url)
linkText=self.gettextonly(link)
self.addlinkref(page,url,linkText)
self.dbcommit()
except:
print("Could not parse %s "% page)
pages=newpages
运行该程序,访问英文网站时速度虽然慢,但没有出错,但是在访问中文网站,如百度,网易等网址时,总是会出现下图所示的错误:
上述的消息提示编码有错误,尝试了将page字符串进行unicode编码,还是不行,后来经过多方搜索,终于在网上找到了问题的答案:http://www.crifan.com/unicodeencodeerror_gbk_codec_can_not_encode_character_in_position_illegal_multibyte_sequence/
原来对于Unicode字符,在Python中如果需要Print出来的话,由于本地系统是Win7的cmd,默认的是GBK编码,所以需要先将Unicode字符编码为GBK,然后在Cmd中显示出来,然而由于Unicode字符串中包含一些GBK中无法显示的字符,导致此时提示“gbk“ codec can't encode的错误的。
解决方式有二:
一:在Print的时候,将unicode字符串进行GBK编码,在编码是添加‘ignore’参数,忽略无法编码的字符,这样就可以正常编码为GBK了。代码如下:
try:
c=urllib.request.urlopen(page)
except:
print("Could not open %s "%page.encode('GBK','ignore'))
continue
二:将Unicode字符串转换为GBK编码的超集GB18030,(即,GBK是GB18030的子集),代码如下:
try:
c=urllib.request.urlopen(page)
except:
print("Could not open %s "%page.encode('GB18030'))
continue