爬虫-英文小说_分析

 文章目录


研究背景(一些废话)

        网络爬虫(又称为网页蜘蛛,网络机器人,在FOAF社区中间,更经常的称为网页追逐者),是一种按照一定的规则,自动地抓取万维网信息的程序或者脚本。

        通俗来讲,假如你需要互联网上的信息,如商品价格,图片视频资源等,但你又不想或者不能自己一个一个自己去打开网页收集,这时候你便写了一个程序,让程序按照你指定好的规则去互联网上收集信息,这便是爬虫,我们熟知的百度,谷歌等搜索引擎背后其实也是一个巨大的爬虫

        爬虫合法吗?

        一般来说只要不影响人家网站的正常运转,也不是出于商业目的,人家一般也就只会封下的IP,账号之类的,不至于法律风险。

       文章的背景:(本文仅作学习交流)

        爬取一篇英文文章,并对其进行分析。文章选择了简爱的小说,分析有词频分析,单词长度统计。附带中文的词云。


提示:以下是本篇文章正文内容,下面案例可供参考

一、相关原理

        网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成。传统爬虫从一个或若干初始网页的URL开始,获得初始网页上的URL,在抓取网页的过程中,不断从当前页面上抽取新的URL放入队列,直到满足系统的一定停止条件。聚焦爬虫的工作流程较为复杂,需要根据一定的网页分析算法过滤与主题无关的链接,保留有用的链接并将其放入等待抓取的URL队列。然后,它将根据一定的搜索策略从队列中选择下一步要抓取的网页URL,并重复上述过程,直到达到系统的某一条件时停止。另外,所有被爬虫抓取的网页将会被系统存贮,进行一定的分析、过滤,并建立索引,以便之后的查询和检索;对于聚焦爬虫来说,这一过程所得到的分析结果还可能对以后的抓取过程给出反馈和指导。

相对于通用网络爬虫,聚焦爬虫还需要解决三个主要问题:

(1)对抓取目标的描述或定义;

(2)对网页或数据的分析与过滤;

(3)对URL搜索策略

        文章采用的环境:

        python 3.9 + bs4 + jieba + matplotlib + wordcloud + PIL + numpy + urllib 

还需要一些前端知识来解析html文本。

具体原理见后。

二、设计思想

爬虫-英文小说_分析爬虫-英文小说_分析

 寻找目标 -》 爬取 -》 保存 -》分析

二、实现过程

1.分析页面

1.爬虫目标

爬虫-英文小说_分析爬虫-英文小说_分析

 2.页面的分析

爬虫-英文小说_分析爬虫-英文小说_分析

 3.章节的URL

第一章:

爬虫-英文小说_分析爬虫-英文小说_分析

第二章:

爬虫-英文小说_分析爬虫-英文小说_分析

 第三章:

爬虫-英文小说_分析爬虫-英文小说_分析

 规律:

第i章的URL为:https://www.24en.com/novel/classics/jane-ey re/ {{1975+i-1}} .html

 由此可的,第28章的url为:

1975+28-1 = 2002

https://www.24en.com/novel/classics/jane-eyre/2002.html
爬虫-英文小说_分析

https :// www.24en.com/novel/classics/jane-eyre/1977.html验证:

爬虫-英文小说_分析爬虫-英文小说_分析

2.引入模块

from bs4 import BeautifulSoup  # 网页解析
import urllib.request, urllib.error  # 指定URL
import jieba    # 分词
from matplotlib import pyplot as plt  # 绘图 数据可视化
from wordcloud import WordCloud     # 词云
from PIL import Image       # 图片处理
import numpy as np      # 矩阵运算
import xlwt  # EXCEL处理
爬虫-英文小说_分析

3.获取数据

        使用库函数,拼接url,循环访问网址,对爬取到的html进行解析,循环保存到txt文档中。

        具体见源代码中的注释。

4.分析数据

        具体见源代码中的注释。             

5.词云

        具体见源代码中的注释。

三、结果展示

 1.英文文本

爬虫-英文小说_分析爬虫-英文小说_分析

2.中文文本

爬虫-英文小说_分析爬虫-英文小说_分析

3.词频及字母数的分析

爬虫-英文小说_分析爬虫-英文小说_分析

爬虫-英文小说_分析爬虫-英文小说_分析

4.词云

爬虫-英文小说_分析爬虫-英文小说_分析

爬虫-英文小说_分析爬虫-英文小说_分析


 四、感想及此项目结构

        项目中功能都完整实现,并进行了功能的封装,比如输出含有字母个数的单词数的函数(可以统计不是特定的数量的单词长度):

#得到 length个及以上的字母的单词个数
def get_count_len(items, length: int):
    count_len_more = 0
    count_text = 0 # 此单词数
    for word, count in items:
        count_text += count
        if len(word) >= length:
            count_len_more += count
    return  count_len_more, count_text
爬虫-英文小说_分析

项目结构:

爬虫-英文小说_分析爬虫-英文小说_分析

爬虫-英文小说_分析爬虫-英文小说_分析

 

        要注意的代码有:

 1.# lambda x:x[0]给列表中元组 的(key)给sort排序,x:x[1]代表字典的值(values)给sort排序,reverse=true表示降序

def sort_dir(dictionary):
    items = list(dictionary.items())
    items.sort(key=lambda x: x[1],
               reverse=True) 
    return items
爬虫-英文小说_分析

  2.# counts.get (word,0)+ 1 是指有word时返回其值,默认是0,+1能够累计次数;没有word时则返回0。

def make_dictionary(text_en):
    words = text_en.split()
    dictionary = {}
    for word in words:
        dictionary[word] = dictionary.get(word, 0) + 1 
    return dictionary
爬虫-英文小说_分析

五、源代码

 1 # -*- coding = utf-8 -*-
 2 # @Time : 2022/1/3 11:35
 3 # @Author : butupi
 4 # @File : spider.py
 5 # @Software : PyCharm
 6 
 7 from bs4 import BeautifulSoup  # 网页解析
 8 import urllib.request, urllib.error  # 指定URL
 9 
10 
11 def main():
12     # 爬取的url_base部分
13     baseurl = "https://www.24en.com/novel/classics/jane-eyre/" #1975-2002
14     # 爬取保存
15     getData(baseurl)
16 
17 
18 # 爬取网页
19 def getData(baseurl):
20     #简爱一共28章
21     for i in range(0, 28):
22         #完整的URL,url起始 的数字是1975,每章的url都是在此基础上加1
23         url = baseurl + str(1975+i)+".html"  # 换页读取
24         #访问网页
25         html = askURL(url)  # 保存获取到的源码
26         # 解析 保存
27         soup = BeautifulSoup(html, "html.parser")
28         with open("wbfx.txt", "a+", encoding="utf-8") as f:
29             f.writelines("\n Chapter"+str(i+1)+" \n")
30             for item in soup.find_all("div", class_="chapter-lan-en toleft"):  # 查找符合要求的字符串
31                 for p in item.p.children:
32                     f.writelines(p.string.replace(u'\xa0', ''))
33         with open("简爱.txt", "a+", encoding="utf-8") as f:
34             f.writelines("\n 第" + str(i+1) + "章 \n")
35             for item in soup.find_all("div", class_="chapter-lan-zh toright"):  # 查找符合要求的字符串
36                 for p in item.p.children:
37                     f.writelines(p.string.replace(u'\xa0', ''))
38 
39 
40 # 爬取指定URL网页信息
41 def askURL(url):
42     #包装request请求头
43     head = {
44         "User-Agent": "Mozilla / 5.0 AppleWebKit " #...
45     }
46     request = urllib.request.Request(url, headers=head)
47     #保存爬取到的网页
48     html = ""
49     try:
50         response = urllib.request.urlopen(request)
51         html = response.read().decode("utf-8")
52         #print(html)
53     #异常处理
54     except urllib.error.URLError as e:
55         if hasattr(e, "code"):
56             print(e.code)
57         if hasattr(e, "reason"):
58             print(e.reason)
59     return html
60 
61 
62 if __name__ == "__main__":
63     main()
64     print("爬取完毕")

 

 

爬虫-英文小说_分析
 1 # -*- coding = UTF-8 -*-
 2 # @Time : 2022/01/03 13:39
 3 # @Author : butupi
 4 # @File : to_wordcloud.py
 5 # @Software : PyCharm
 6 
 7 import jieba    # 分词
 8 from matplotlib import pyplot as plt  # 绘图 数据可视化
 9 from wordcloud import WordCloud     # 词云
10 from PIL import Image       # 图片处理
11 import numpy as np      # 矩阵运算
12 
13 
14 #---------------------------------
15 #获取中英文文章
16 def get_text(path_en, path_zh):
17     text_en = ""
18     text_zh = ""
19     with open(path_en, "r", encoding="utf-8") as f:
20         for line in f.readlines():
21             text_en += line.rstrip("\n")
22     # print(text_en)
23     with open(path_zh, "r", encoding="utf-8") as f:
24         for line in f.readlines():
25             text_zh += line.rstrip("\n")
26     return text_en, text_zh
27 
28 #---------------------------------
29 
30 #jieba分词
31 def cut_text(text):
32     cut = jieba.cut(text)
33     cut_words = ' '.join(cut)
34     # print(type(cut_words))
35     # print(len(cut_words))
36     return cut_words
37 
38 #---------------------------------
39 #得到停用词列表
40 def get_stop_words(filepath):
41     stop_words = [line.strip() for line in open(filepath, 'r', encoding='utf-8').readlines()]
42     return stop_words
43 
44 #去除停用词
45 def move_stop_words(text, path):
46     stop_words = get_stop_words(path)
47     out_str = ''
48     for word in text:
49         if word not in stop_words:
50             if word != '\t' and '\n':
51                 out_str += word
52     return out_str
53 #-----------------------------------
54 
55 #生成词云
56 def get_word_cloud(source_path, dest_path, out_str):
57     #得到背景图片
58     img = Image.open(source_path)
59     #将图片转换为数组
60     img_array = np.array(img)
61     #词云属性
62     wc = WordCloud(
63         background_color='white',
64         mask=img_array,
65         font_path="msyh.ttc"       # font
66     ).generate_from_text(out_str)
67 
68     #绘制图片
69     fig = plt.figure(1)
70     plt.imshow(wc)      # 以词云的方式显示
71     plt.axis('off')     # 不显示坐标
72     #plt.show()  # 显示生成的词云图片
73     #输出为文件
74     plt.savefig(dest_path, dpi=500)
75 
76 #-------------------------------
77 def main():
78     #get_text
79     text_en, text_zh = get_text("wbfx.txt", "简爱.txt")
80 
81     #jieba
82     cut_words = cut_text(text_zh)
83 
84     #move_stop_words
85     out_str = move_stop_words(cut_words, 'stop_word.txt')
86 
87     #wordcloud
88     get_word_cloud('zh-tree.jpg', 'zh-tree-out.jpg', out_str)
89     get_word_cloud('en-bj.png', 'en-bj-out.png', text_en)
90 
91 
92 #---------------------------------
93 if __name__ == '__main__':
94     main()

 

爬虫-英文小说_分析
 1 # -*- coding = utf-8 -*-
 2 # @Time : 2022/01/03 20:45
 3 # @Author : butupi
 4 # @File : word_frequency.py
 5 # @Software : PyCharm
 6 
 7 import xlwt  # EXCEL处理
 8 
 9 #获取英文文章(替换特殊字符)
10 def get_text(path_en):
11     text_en = ""
12     with open(path_en, "r", encoding="utf-8") as f:
13         for line in f.readlines():
14             text_en += line.rstrip("\n")
15     #小写
16     text_en = text_en.lower()
17     #替换特殊字符
18     for ch in '!"#$&()*+,-./:;<=>?@[\\]^_{|}·~\'‘’':
19         text_en = text_en.replace(ch, " ")
20     return text_en
21 
22 
23 #处理文本存入字典
24 def make_dictionary(text_en):
25     words = text_en.split()
26     dictionary = {}
27     for word in words:
28         dictionary[word] = dictionary.get(word, 0) + 1  # counts.get (word,0)+ 1 是指有word时返回其值,默认是0,+1能够累计次数;没有word时则返回0。
29     return dictionary
30 
31 #排序
32 def sort_dir(dictionary):
33     items = list(dictionary.items())
34     items.sort(key=lambda x: x[1],
35                reverse=True)  # lambda x:x[0]给列表中元组 的(key)给sort排序,x:x[1]代表字典的值(values)给sort排序,reverse=true表示降序
36     return items
37 
38 #得到 length个及以上的字母的单词个数
39 def get_count_len(items, length: int):
40     count_len_more = 0
41     count_text = 0 # 此单词数
42     for word, count in items:
43         count_text += count
44         if len(word) >= length:
45             count_len_more += count
46     return  count_len_more, count_text
47 
48 #保存到EXCEL表格中
49 def save_sheet(path, items):
50     workbook = xlwt.Workbook(encoding="utf-8")
51     worksheet = workbook.add_sheet("word_frequency")
52     worksheet.write(0, 0, "单词")
53     worksheet.write(0, 1, "出现次数")
54     for i in range(0, len(items)):
55         worksheet.write(i+1, 0, items[i][0])
56         worksheet.write(i+1, 1, items[i][1])
57     workbook.save(path)
58 
59 #统计单词、词频
60 def main():
61     text_en = get_text("wbfx.txt")
62 
63     #对处理后的文本进行词频统计存入字典
64     dictionary = make_dictionary(text_en)
65 
66     #将字典降序排列,得到列表,元素为(k-v)元组(单词,频次)
67     items = sort_dir(dictionary)
68 
69     #统计结果存为列表类型,按词频由高到低进行排序,输出前15位
70     print("简爱英文小说 Jane Eyre 词频前15排行")
71     for i in range(15):
72         word, count = items[i]
73         print("{0}\t\t{1:<8}{2:>5}".format(i+1, word, count))
74 
75     #保存到Excel表格中
76     save_sheet("word_frequency.xls", items)
77 
78     #6个字母长度及以上的单词个数
79     length_word = 6
80     count_six_more, count_text = get_count_len(items, length_word)
81     #print(word, count)  # 6个字母+的单词及其频次
82     print()
83     print("简爱小说英文文本中"+str(length_word)+"个及以上的字母的单词个数有:\t"+str(count_six_more)+" 个")
84     print("简爱小说英文Jane-Eyre文本总共有单词个数有:\t"+str(count_text)+" 个")
85 
86 
87 if __name__ == '__main__':
88     main()

 

爬虫-英文小说_分析


上一篇:Tencent_机器翻译_文本翻译


下一篇:Johnson 全源最短路径算法学习笔记