现在公司这边需要一批电影的词库,一方面是一堆现有的文件中提取整合,另一方面需要自己去爬取。以下就以这两个方面来分别介绍一下。
1.1 如何将一个文件夹下的一堆文件整合成一个文件,把数据合并
这里需要用到os这个库,os.listdir(filepath)会返回该路径下所有文件的一个迭代器,然后再分别把这些文件用for循环打开,把里面的内容提取出来,用一个第三方的变量存储,最后所有的都读完之后,就把这个变量单独存成一个txt,这就是思路。
程序代码可以参考以下以下几行:
import os
filenames=os.listdir(datafile)
for filename in filenames:
with open(datafile+filename, encoding='utf-8') as f:
for line in f.readlines():
prewordlist.append(line.replace("\n",""))
这个执行完之后,会得到一个prewordlist,这里面存储了所有文件中的词汇组成的列表。
1.2 如何对list进行去重
与list这种数据结构平行的还有一个set(集合),set的特点就是里面不存在重复的数据,可以直接使用set(list)将一个list转换为set,也可以将一个list(set)将一个set转换为list。 此外,set还可以进行求交集,并集和差集。
例如在这里,如果我们想对于prewordlist进行去重处理得到新的list,可以进行如下操作,
prewordlist=list(set(prewordlist))
如果想得到两个list之间的交集list,可以进行如下操作:
common_list = list(set(prewordlist).intersection(set(newwordlist)))
如果我们想删除list中的第i个元素,可以使用pop()
list.pop(i)
得到list的实际元素个数
len(list)
1.3 如何判断一个字符串中是否含有特殊字符?
所谓的“特殊字符”可以理解成除了汉字、数字、英文字母之外的其它字符,如标点符号,日语,五角星等等。其基本的判断思路就是对于字符串中的每一个字符进行遍历,看看其是否是汉字、数字、英文字母,判断的依据是根据各个字符的ASCII码或者Unicode吗。
具体代码参考如下(使用Unicode码):
def is_chn(uchar):
if uchar >= u'\u4e00' and uchar <= u'\u9fa5':
return True
else:
return False
def is_num(uchar):
if uchar >= u'\u0030' and uchar <= u'\u0039':
return True
else:
return False
def is_word(uchar):
if ( uchar >= u'\u0041' and uchar <= u'\u005a' ) or ( uchar >= u'\u0061' and uchar <= u'\u007a'):
return True
else:
return False
def judge(ustring):
for s in ustring:
if s is not '\n':
if (is_chn(s) or is_num(s) or is_word(s)) is False:
return False
return True
1.4 如何将字符串中英文和数字的全角转成半角
全角半角的概念:
全角是指一个字符占用两个标准字符位置,半角是指一个字符占用一个标准字符位置。全角占两个字节,半角占一个字节。通常的编程语言中,都是使用半角字符。汉字默认是全角的,因此中文里面的句号是一个圆圈,而英文半角的句号只是一个点。
在ASCII码中,全角字符的ASCII码值比对应的半角字符多65248。因此这里只需要首先获得其ASCII码值,然后对于英文和数字,如果是全角,将其减去65248,再进行解码即可,程序代码参考如下:
def w2h(ustring):
"""全角转半角"""
rstring = ""
for uchar in ustring:
inside_code=ord(uchar)
if inside_code == 12288: #全角空格直接转换
inside_code = 32
elif (inside_code >= 65281 and inside_code <= 65374): #全角字符(除空格)根据关系转化
inside_code -= 65248
rstring += chr(inside_code)
return rstring
2 对于三个网站(豆瓣、电影天堂,一起搜电影)进行爬取的方法还是与之前的介绍类似,首先使用requests库的get方法获得html网页,再利用pyquery分析网页中的内容,把需要的信息提取出来,保存。以下直接粘贴以下代码:
电影天堂:
#coding=utf-8
import chardet
import requests
from pyquery import PyQuery as pq
import re
movie=[]
movie_list=[]
for page in range(1, 177):
print(page)
url='http://www.ygdy8.net/html/gndy/dyzz/list_23_'+str(page)+'.html'
response=requests.get(url)
text = response.text.encode('iso-8859-1').decode('gbk','ignore')#这一步搞了一下午T_T
doc=pq(text)
moviename=doc('#header .contain .bd2 .bd3 .bd3r .co_area2 .co_content8 table tr b a')
pattern = re.compile(r'《(.+?)》')
movie_list = re.findall(pattern,moviename.text())
movie.extend(movie_list)
#print(movie)
movie=list(set(movie))
s = "\n".join(movie)
datapath='D:/输出词库/电影天堂电影/'+'zuixin'+'.txt'
with open(datapath,'w') as f:
f.write(s)
f.close()
一站搜电影:
#coding=utf-8
import chardet
import requests
from pyquery import PyQuery as pq
import re
movie=[]
movie_list=[]
for page in range(1, 497):
print(page)
url='http://v.yizhansou.com/mv/?p='+str(page)
response=requests.get(url)
#text = response.text.encode('iso-8859-1').decode('gbk','ignore')
text=response.text
doc=pq(text)
moviename = doc('tr .xt a')
movie_list=moviename.text().split()
movie.extend(movie_list)
#print(movie)
movie=list(set(movie))
s = "\n".join(movie)
datapath='D:/输出词库/一站搜电影/'+'yizhansou'+'.txt'
with open(datapath,'w') as f:
f.write(s)
f.close()
这些网站的资源毕竟过小,加一起也就两万左右,偶然发现了一个很棒的电影索引网站,电影FM,但是在爬取过程中发现,如果page>50的话,需要登陆后才可以继续获得网页。这里就牵扯到一个表单的问题,搞了一天也没搞出来,但是学习了fidder抓包软件的使用,将在下一节进行分享。