网页抓取解密(编码与解码字符和字节的编码(encode))
优采云 发布时间: 2021-10-14 05:17网页抓取解密(编码与解码字符和字节的编码(encode))
p1_1 clearfix'style="display: block;"> 模块。
后来问了前辈,发现F12快捷键只是一个html开发工具。如果要查看真正的源代码,需要右击选择“查看网页源代码”。
我选择将代码复制到UltraEdit中查看,因为直接查看太难找到我想要的信息了。
3. 编码和解码
我一直觉得很难理解字符和字节的编码和解码。之前转载了一篇文章的文章,很不错,链接如下:
简单来说就是人类可以识别的字符,比如中文和英文;字节可以被机器识别。将机器可识别的字节转换为人类可识别的字符称为解码;将人类可识别的字符转换为机器可识别的字节称为编码。Python2.x 是最容易出现编解码问题的(我有时候觉得Python2对中文有仇)。在python3.x中,由于默认编码是Unicode(一种涵盖世界上所有语言的编码),所以出现此类问题的概率大大降低。至于各种代码的特点和历史,请参考上面推荐的文章。
程序运行时,开始写f.write(fs.text),报如下错误:
’gbk’ codec can’t encode
后来,代码改为:
f.write(re.sub('\u2002','',fs.text))
它运行成功。
值得注意的是,修改前的代码在Unix系统下可以正常运行,但是在我的Windows7系统下会报错。
后来通过百度,发现了问题的根源:
在Windows 7系统中,cmd的默认编码是gbk。如果需要输出,必须先将字节编码为gbk(我不是很懂),gbk和中文不能完全匹配,出现错误。
幸运的是,gbk 可以编码大部分中文,所以只需要屏蔽少数无法识别的字符。
我很佩服发现这种错误的人。他一定是搜索了很久,阅读了大量的源代码才发现。这是处理错误的方法。一次处理的马虎,日后可能会惹上*敏*感*词*烦。
二. 图片爬取
以上代码进一步完善,官方文档和官方照片同时抓取。
完整代码如下(基于Python3.6):
# -*- coding: utf-8 -*-
"""
Spyder Editor
This is a temporary script file.
"""
from urllib import request
from bs4 import BeautifulSoup
import re
import os
url='http://cpc.people.com.cn/gbzl/flcx.html'#给出要爬取的总网址
head={}
head['User_Agent']='Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/536.6 (KHTML, like Gecko) Chrome/20.0.1092.0 Safari/536.6'
#设置代理,假装是用户访问. 注意,服务器会限制部分user-agent,如果程序报错,就换一个。
#user-agent的获取可参考以下网址:http://blog.csdn.net/bone_ace/article/details/52476016
req=request.Request(url,headers=head)#给请求装上代理
response=request.urlopen(url)#打开url
res=response.read().decode('UTF-8')#读取网页内容,用utf-8解码成字节
soup=BeautifulSoup(res,'lxml')#将网页的内容规范化
soup_links=soup.find('div',{'class':"p1_1 clearfix"}).find_next('div',{'class':"p1_1 clearfix"}).find_next('div',{'class':"p1_1 clearfix"})
#通过解析html,发现第3个div是我们想爬取的内容
tab=soup_links.find_all('table')#找到当前div下所有的table标签
capital=soup_links
f1=open('D:/Data_Rabbit/jianli/omit.txt','w')#打开omit文件,记录读取信息失败的官员名字
for i in range(0,len(tab)):
capital=capital.find_next('div')#找到对应的省的名字
mdir='D:/Data_Rabbit/jianli/'+capital.string+'/'
if not os.path.exists(mdir):#如果当前文件夹不存在,则创建之
os.mkdir(mdir)#新建文件夹,以省份名字命名
trs=tab[i].find_all('tr')
for trIter in trs:
tds=trIter.find_all('td')
for tdIter in tds:
mdir1=mdir+tdIter.string+'/'
if not os.path.exists(mdir1):
os.mkdir(mdir1)
file=mdir1+tdIter.string+'.txt'
f=open(file,'w')#刚才创建的文件夹路径下,新建一个以领导名字命名txt文件
s=tdIter.a.get('href')#得到某*敏*感*词*的链接
url_p='http://gbzl.people.com.cn/grzy.php?id='+re.findall('\d+',s)[0]#用正则表达式合成某*敏*感*词*的信息网址
r0=request.urlopen(url_p)#打开某*敏*感*词*信息的网页
r=r0.read().decode('UTF-8')
soup_p=BeautifulSoup(r,'lxml')
fs=soup_p.find('p',{'class':'jili'})
if fs==None:#如果读取失败
f1.write(tdIter.string+':'+url_p+'\n')#记录*敏*感*词*名字和网址
else:
f.write(re.sub('\u2002','',fs.text))#记录*敏*感*词*信息。忽略‘\u2002’这个字符,因为如果不这样的话,系统会报错,导致无法运行。
'''''具体原因如下(百度):对于此Unicode的字符,需要print出来的话,由于本地系统是Win7中的cmd,默认codepage是CP936,即GBK的编码,
所以需要先将上述的Unicode的titleUni先编码为GBK,然后再在cmd中显示出来,然后由于titleUni中包含一些GBK中无法显示的字符,导致此时提示
“’gbk’ codec can’t encode”的错误的。'''
f.close()
#下面开始爬取图片
pic=soup_p.find('div',{'class':'gr_img'})
if pic !=None:
pic_link=pic.find('img').get('src')
pic_name=mdir1+'1.jpg'
request.urlretrieve(pic_link, pic_name)
f1.close()
了解爬虫后,完成任务的速度提高了。参考了一些网友的智慧,我花了一个小时左右的时间来改代码(其实已经够长了,遮脸)。
文章我主要参考了一个博客,我已经在我的博客上转发了,链接如下:
我只添加了5行代码就完成了图片爬取。这不仅是因为我对爬虫很熟悉,更大的原因是上一步已经完成了各个leader信息URL的合成。在知道某个网页的网址的情况下,抓取图片就容易多了。
我分析的整个网页只收录一张图片。所以我们不用区分要爬取的图片,复制图片即可。在网页中,每张图片对应一个 URL。只要获取到图片的URL,我们就可以通过如下代码进行抓取:
request.urlretrieve(pic_link, pic_name)
其中,pic_link表示图片的URL,pic_name表示图片的名称(注意这个名称中收录路径,如:'D:/data/1.jpg')。
那么,如何获取图片的URL呢?方法和上一篇的爬取文本信息的方法类似,只不过我们现在要爬取的变成了一个URL(可以理解为和爬取官方对应的URL一样的工作)。
在初始编码中,遇到错误:AttributeError:'NoneType' object has no attribute'find'。说实话,这种错误我已经不是第一次遇到了,不过还是得靠百度来解决(这个习惯不好,尽量改掉)。在开始的代码中,我没有添加以下语句:
if pic !=None:
我直接用下面这句话来替换前三行:
pic_name=soup_p.find('div',{'class':'gr_img'}).find('img').get('src')
而不是目前的写作方式:
pic=soup_p.find('div',{'class':'gr_img'})
if pic !=None:
pic_link=pic.find('img').get('src')
结果出错了。
后来在StackOverflow上找到了原因(一个不错的网站,程序报错时可以求助)。原来在各个官方的信息网页上都找不到标签'div',{'class':'gr_img'},soup_p.find('div',{'class':'gr_img'} ) 可能返回空值无。而 None.find('img') 显然是错误的说法。
还有一段代码需要解释一下:
pic_link=pic.find('img').get('src')
这句话的作用是找到
标记,并在其中获取 src(即图像 URL)。
网页的部分html代码如下:
至此,第二步完成。但是代码还是有问题:部分官员信息爬不下来(文字和图片爬不下来),具体原因我还没分析,留待以后补完.
PS:周末了。我打算明天出去放松一下。祝大家周末愉快:-D
三方和信息提取
哈尔滨工业大学开发的一个包在这里叫做:pyltp。这个包的下载、配置和使用可以参考官方文档,链接如下(中文):
pyltp可以完成中文分词、分词、词性标注、命名实体识别、依存句法分析(主谓、动宾等。说实话,作为一个人,我是分辨不出来的) ,语义角色标注(标记词和谓词)关系)。
所以分词和命名实体识别(信息提取)这两个任务都可以使用pyltp来完成。
命名实体识别的简单定义如下:
命名实体识别(NER)是自然语言处理(NLP)的一项基本任务,其目的是识别语料库中的人名、地名、组织名称等命名实体。