用python爬取考研词汇及其近反义词与例句

前期准备

运行环境:jupyter notebook 或者 pycharm
python版本:python3.x
浏览器:chrome
需要用到的库:

requests
bs4
os
enchant
json
time

可能需要安装的库

pip install requests -i https://pypi.tsinghua.edu.cn/simple
pip install Beautifulsoup4 -i https://pypi.tsinghua.edu.cn/simple
pip install pyenchant -i https://pypi.tsinghua.edu.cn/simple

思路

先找到有考研单词的网站,爬取词汇。
将爬取的词汇放进单词搜索网站上检索,爬取其近反义词及其例句
最终保存到json格式的文件里。
在这里插入图片描述

爬取流程

爬取词汇

爬取网址:http://word.iciba.com/?action=courses&classid=13

导入相应的库
import requests
from bs4 import BeautifulSoup
import os
import enchant
import json
from time import sleep
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36", 
          "cookie": "UM_distinctid=1785a4cc9f7303-069f2552a41de7-5771031-144000-1785a4cc9f856b", 
           "upgrade-insecure-requests": "1"
          }
获取网页源代码
# 获取网页源代码
def get_html(url):
    try:
        r = requests.get(url=url, headers=headers)
        r.raise_for_status()
        print("text状态:", r.raise_for_status)
        r.encoding = r.apparent_encoding
        return r.text
    except Exception as result:
        print("错误原因0:", result)
        return ''
获取单词和意思

这部分是爬取单词的核心部分,我们一步一步分析看看.
打开网址,可以看到这里有一个词汇列表。

在这里插入图片描述
按Ctrl+Shitf+i,打开开发者调试页面,按Ctrl+Shift+C,然后将鼠标悬空在列表页面上
在这里插入图片描述
可以快速定位到我们需要分析的内容
我们可以发现course_id是有规律的在变化。
我们点开第一个列表
在这里插入图片描述
可以看到url里也有一个course将course=1改成course=2
在这里插入图片描述
我们就跳转到第二页,这个规律就找到了。我们就可以通过遍历的方式爬取所有单词。

接下来就是爬取每一个单词和词汇。
按Ctrl+Shift+i,再定位到某个单词上
在这里插入图片描述
可以看到这里有个< li>列表,点开看看里面有什么。

在这里插入图片描述
可以看到我们想要的东西就在< span>里(音标在< strong>里, 这里就不爬音标了,想要的可以自行添加代码)。
通过以上分析我们可以得出分析结果:

我们可以通过修改course的值来进行翻页。每个单词和意思都在< li>里,而单词和意思在< li>里的< span>里

所以代码可以如下这样写

# 获取单词和意思
def get_words(text):
    word_dict = dict()
    soup = BeautifulSoup(text, 'lxml')
    for each in soup.find_all('li' ):
        span = each.select('span')
        word_dict[span[0].attrs['title']] = span[1].attrs['title']
    return word_dict

一个小细节
本来可以直接span.text.strip()来获取文本,为什么最终是用了span.arrts[‘title’]来获取文本呢?
看了这图就不言而喻了。
在这里插入图片描述
爬取词汇的核心部分解决了,那么就来分析后面该怎么做了。
方案一
先爬取所有的词汇,然后保存。然后将单词从本地取出来放入单词搜索网站上,一个一个爬下来,最后再保存。
方案二
爬一页词汇列表,然后将该页词汇列表里的单词放入搜索网站上搜索,爬取后保存。

这两个方法都有利有弊,因为我都试过了。第一次用的是方案一,因为忘记设置sleep,导致爬取速度过快,被封ip了。所以我这次就用第二种,交替爬取两个网站,再设置sleep,降低访问频率。

爬取单词的近反义词及其例句

网址:http://dict.cn/
在这里插入图片描述
随便输入一个单词
在这里插入图片描述
可以看到搜索后就是在网址后直接加入被搜索单词,那么这个也可以通过遍历搜索所有单词的近反义词和例句。

分析例句

在这里插入图片描述

通过定位可以找到在< div class=“layout sort”>容器里的< ol>下有< li>这< li>里就是例句
在这里插入图片描述
核心代码就可以这样写

div = soup.find('div', class_="layout sort")
for li in div.select('li'):
	print(li.text)
爬取近反义词

定位到近反义词部分
在这里插入图片描述
我们仔细分析一下可以发现,近反义词的词汇都在< div class=“layout nfo”>里,近反义词的词汇都存储在各自的< ul>里,如果通过< ul>的位置顺序来判断近反义词,也许会出错。例如data这个单词,只有近义词。
在这里插入图片描述
所以我们需要另外一种方法
比如在< div class=“layout nfo”> 里还有< div>,里面存放的就是**【近义词】和【反义词】**,那么我们可以通过这个来顺藤摸瓜,直到遇见< ul>节点。然后我们就可以爬到< ul> 节点下的所有< li>子节点
在这里插入图片描述
< li>里还有一个< a>,里面既有英文又有中文,但是good这个单词里的近反义词就没有中文。
在这里插入图片描述
所以就需要用列表来存储。

word_li = []
for i in soup.find_all('li'):
    if i.text.strip():
        word_li.append(i.text.strip().split())

那么核心部分都分析完了,就要分析存储结构了。

word_all_dict[word] = {"translate":"", 
                        "homoionym":{[英文单词列表]}, 
                        "antonym":{[英文单词列表]},
                        "sentence":[英文句子中文翻译]}

这是我的存储结构。

开始撸代码

import requests
from bs4 import BeautifulSoup
import os
import enchant
import json
from time import sleep
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.90 Safari/537.36", 
          "cookie": "UM_distinctid=1785a4cc9f7303-069f2552a41de7-5771031-144000-1785a4cc9f856b", 
           "upgrade-insecure-requests": "1"
          }

# 获取网页源代码
def get_html(url):
    try:
        r = requests.get(url=url, headers=headers)
        r.raise_for_status()
        print("text状态:", r.raise_for_status)
        r.encoding = r.apparent_encoding
        return r.text
    except Exception as result:
        print("错误原因0:", result)
        return ''

# 获取单词和意思
def get_words(text):
    word_dict = dict()
    soup = BeautifulSoup(text, 'lxml')
    for each in soup.find_all('li' ):
        span = each.select('span')
        word_dict[span[0].attrs['title']] = span[1].attrs['title']
    return word_dict

# 获取近反义词的关键函数
def check_word(tag):
    soup = BeautifulSoup(str(tag), 'lxml')
    word_li = []
    for i in soup.find_all('li'):
        if i.text.strip():
            word_li.append(i.text.strip().split())
    return word_li

def get_word_all(word, translate, search_text):
    """
    word: 关键词
    translate: word的中文意思
    search_text:word的爬虫文本
    """
    # 创建一个字典
    word_all_dict = dict()
#     word_all_dict[word] = {"translate":"", 
#                            "homoionym":{[英文单词列表]}, 
#                            "antonym":{[英文单词列表]},
#                            "sentence":[英文句子中文翻译]}
    word_all_dict[word] = {"translate":translate, "homoionym":list(), "antonym":list(), "sentence":list()}
    # 制作一碗毒鸡汤
    soup = BeautifulSoup(search_text, 'lxml')
    # 获取例句
    for each in soup.find('div', class_="layout sort").select('li'):
        word_all_dict[word]["sentence"].append(each.text)
    # 爬取近反义词
    soup = soup.find('div', class_="layout nfo")
    for tmp in soup.select('div'):
        print(tmp.text)
        if "近义词" in tmp.text:
            word_all_dict[word]["homoionym"] = check_word(tmp.next.next.next)
        if "反义词" in tmp.text:
            word_all_dict[word]["antonym"] = check_word(tmp.next.next.next)
    return word_all_dict

# 保存成json格式
def save_word_json(word, word_dict):
    path = 'D:/English/'
    if not os.path.exists(path):
        os.makedirs(path)
    str_dict = json.dumps(word_dict)
    fp = open(path+'Words.json', 'a+')
    fp.write(str_dict)
    fp.write('\n')
    fp.close()
    print(f"{word}保存成功!")

# 读取加载json文件
def load_json():
    path = 'D:/English/WordPhonetic.json'
    with open(path, 'r') as fp:
        data = fp.readlines()
    for each in data:
        word_dict = json.loads(each)
        print(word_dict)

def main():
    count = 0
    for i in range(1, 275):
        print(f"正在爬取第{i}个单词网页")
        url = f'http://word.iciba.com/?action=words&class=13&course={i}'
        text = get_html(url)
        all_word_dict = get_words(text)
        for word in all_word_dict:
            print(f"正在爬取第{count+1}个单词:{word}")
            wurl = 'http://dict.cn/'+word
            search_text = get_html(wurl)
            if not search_text:
                continue
            try:
                word_all = get_word_all(word, all_word_dict[word], search_text)
                save_word_json(word, word_all)
            except Exception as result:
                print(f"{word}保存失败,错误为:", result)
            sleep(2)
            count += 1

main()

注意

  1. 需要读取的话就用load_json()函数读取。
  2. 最终爬取的结果会被保存到D:/English/目录下,没有此目录,代码也会自动创建
  3. 写入模式是追加模式,切不可重复运行,不然内容只会追加,不会覆盖。
  4. 可以修改for i in range(1, 275)里的数字,进行分步爬取。
  5. 可以下载一个Visual Studio Code 软件,打开json文件。
  6. 要花大概两个小时才能运行完
  • 3
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是强筱华哇!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值