更加完善的爬虫 plus

算上注释,和一些意义不明的回车,大概五百行。

总之就是:

  • 使用controller控制页面的切换,实现了return,而且不用像之前一样重复实例化多个窗口(在connect里面实时实例化)。
  • 优化了UI的布局。
  • 进行了exe打包
  • 增加了功能:
    • 使用jieba进行分词
    • 使用word2vec进行 句子-词向量 的转化
    • 使用pandas将测到的结果写入csv文件

Controller 控制器

核心是Qt的信号量机制。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# 利用一个控制器来控制页面的跳转
class Controller:
def __init__(self):
pass
# 跳转到 main 窗口
def show_main(self):
self.main = mainpage()
self.main.switch_window1.connect(self.show_add_url) # 信号量关联
self.main.switch_window2.connect(self.show_crawler)
self.main.show()

# 跳转到search窗口, 注意关闭原页面
def show_add_url(self):
self.add_url = addurl()
self.add_url.switch_window1.connect(self.show_main)
self.add_url.switch_window1.connect(self.add_url.close)
self.main.close()
self.add_url.show()

#跳转到 DisFac 窗口, 注意关闭原页面
def show_crawler(self):
self.crawler = crawler()
self.crawler.switch_window1.connect(self.show_main)
self.crawler.switch_window1.connect(self.crawler.close)
self.main.close()
self.crawler.show()

可以看到,函数中调用的self.xxx.switch_window1是原类中的一个pyqtSignal()对象,本质是Qt使用的信号量。在类的开头进行实例化:
1
switch_window1=pyqtSignal()

实例化后就可以调用其中的emit()方法,在这里,方便起见,我另外设置了一个方法来调用。

具体内容为:

1
2
def return_to_main(self):
self.switch_window1.emit()

而与之对应,在主页面也有对应方法,用于和对应的跳转按钮对应起来:

1
2
3
4
5
6
7
8
9
10
switch_window1=pyqtSignal()
switch_window2=pyqtSignal()

def jump_to_add_url(self):
print('jump to add url')
self.switch_window1.emit()

def jump_to_crawler(self):
print('jump to crawler')
self.switch_window2.emit()

总之就是,使用pyqtSignal()对象中的emit()方法进行跳转。在Controller内,这个pyqtSignal()对象应该和形如show_add_url的方法对应起来。

UI的优化

主页:
主页

添加url:
添加url

爬取:
爬取

exe打包

使用了pyinstaller,值得注意的是,当前虚拟环境(我用了anaconda)里,没有用到的包似乎也会被一并打包,导致最终的exe巨大一个。

要是需要小一点的exe,可以新建虚拟环境,并尽量少地安装包。

readline 和 rstrip(“\n”) 和 split(‘ ‘)

readline真的是只读一行,读到回车为止。

rstrip是一个字符串的方法,可以删去字符串首尾的多余字符。例如skipwords[i] = skipwords[i].rstrip("\n")

split也是一个字符串的方法,可以以参数为界,将字符串切割为列表。

for

cutwordslist += [word for word in jieba.cut(word_read, cut_all=False) if word not in skipwords]

C for A in B,用中括号括起来就是一个列表,甚至可以用if进行跳过。很神奇。

eval 和 dict

理论上dict可以将字符串转化为字典,但是我从来没使用成功过,反倒是一直在用eval

jieba 分词

cutwordslist += [word for word in jieba.cut(word_read, cut_all=False) if word not in skipwords]

jieba.cut方法,输入需要切割的字符串,指定切割模式,返回一个列表。

word2vec

首先加载模型,w2v_model = Word2Vec.load('aaa.model')

然后,由于我使用的向量是一百二十八维的(主要是因为模型就是这个维数),所以需要更新大小。

vec = numpy.zeros(size).reshape((1, size))

要想获得一句话的词向量,只需要将词汇的词向量全部相加。

vec += w2v_model.wv[word].reshape((1, size))

获得vec之后写入即可。

pandas 写入 csv

pandas使用的数据类型叫做DataFrame,初始化的时候需要提供数据和标签,datacolumns

data=pandas.DataFrame(data=[j for j in range(128)],columns=['index'])

写入新数据是data[line]=vec[0],其中line为句子本身的字符串,作为索引,vec是一个列表套列表所以不能直接用,需要vec[0]

如果vec维数不够128维就会出现报错,以防万一,使用if判断,然后data[line]=[0 for k in range(128)]进行补零。

最后写入:data.to_csv('data_final_'+self.site+'.csv')


更加完善的爬虫 plus
http://petertan303.github.io/2023/05/28/更加完善的爬虫-plus/
作者
peter?
发布于
2023年5月28日
许可协议