面试中最常被问到的竟然是...

 

通过Python爬取牛客网面经并分词统计

通过Python爬取牛客网面经并分词统计

俗话说:“知己知彼,百战不殆”,在准备面试的过程中,大家基本都会在网上搜集前辈们的面经,借此来了解各个公司在面试过程中常常提问的问题,这样就能够针对性的做出准备

那你想不想知道,在某个领域,最常被提问到的知识点是什么呢?使用Python写一个脚本,马上就能知道

1.爬取面经

牛客网为例

首先打开面经汇总页面

在这里插入图片描述

找到自己感兴趣的领域或者公司,这里我选择了golang

在这里插入图片描述

点开之后发现面经内容相关的部分是通过Ajax加载的,如果直接爬取页面是得不到这些内容的

读取Ajax可以使用Python的selenium库,通过WebDriverWait方法可以等待Ajax加载之后再读取内容

具体实现如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

driver = webdriver.Chrome(executable_path='C:/user/selenium/chromedriver.exe')  # 自己的chromedriver位置
driver.get('https://www.nowcoder.com/discuss/experience?tagId=2656')  # 对应的页面url

# 等待ajax内容加载
wait = WebDriverWait(driver, 10)
# 一直等到 class='js-nc-wrap-link'(对应页面的ajax部分)加载出来
wait.until(
    EC.presence_of_element_located((By.CLASS_NAME, 'js-nc-wrap-link'))
)
  • 注意,由于selenium要调用浏览器,所以首先要下载对应浏览器的驱动,这部分在selenium官方文档中有详细说明

等Ajax加载完毕,就可以获得每一条面经对应的链接了,不过每次打开页面,默认只会显示20几条内容,需要向下刷新页面才能继续加载,所以为了一次性能所爬取一些内容,需要一个模拟页面下滑的函数:

def scrollPage(timeout, times):
    for i in range(times):
        print('next')
        # 向下刷新一次内容
        driver.execute_script('window.scrollTo(0,Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight));')
        time.sleep(timeout)

两个参数,timeout指的是隔多久向下刷新一次,times指的是一共刷新几次,可以按照自己的需要来改动

等到页面信息全加载出来,爬取的方式就很多了,我用的是beautifulsoup,整个爬虫的代码如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import requests
from bs4 import BeautifulSoup
import time

BASE_URL = 'https://www.nowcoder.com'

driver = webdriver.Chrome(executable_path='P:/selenium/chromedriver.exe')
driver.get('https://www.nowcoder.com/discuss/experience?tagId=2656')  # 对应的页面

# 等待ajax内容加载
wait = WebDriverWait(driver, 10)
wait.until(
    EC.presence_of_element_located((By.CLASS_NAME, 'js-nc-wrap-link'))
)

def scrollPage(timeout, times):
    for i in range(times):
        print('next')
        # 向下刷新一次内容
        driver.execute_script('window.scrollTo(0,Math.max(document.documentElement.scrollHeight,document.body.scrollHeight,document.documentElement.clientHeight));')
        time.sleep(timeout)

# 以3秒的间隔向下刷新5次内容
scrollPage(3, 5)

# 带有 class='js-nc-wrap-link' 属性的标签都是面经的链接
items = driver.find_elements_by_class_name('js-nc-wrap-link')

with open('content.txt', 'w', encoding='utf-8') as f:
    # 逐个读取每一个链接中的文本,并写到文件里面
    for item in items:
        print(item.get_attribute('data-href'))
        response = requests.get(BASE_URL + item.get_attribute('data-href'))
        data = response.text
        soup = BeautifulSoup(data, 'html.parser')
        words = soup.find('div', {'class': 'post-topic-des nc-post-content'})
        f.write(words.get_text())

2.分词统计

在上一节中,我们爬取到了想要的面经内容,并以文本的形式保存到了文件中,有了这个文件,就可以统计其中的词频

我这里使用Python的jieba库来实现分词

import jieba

# 读取文本内容
with open('content.txt', 'r', encoding='utf-8') as f:
    data = f.read()

# 分词
count = jieba.lcut(data)
word_count={}
for word in count:
    if len(word) == 1:  # 去掉标点符号等无意义的字符
        continue
    word_count[word] = word_count.get(word, 0) + 1

# 按词频对分词进行排序
items = list(word_count.items())
items.sort(key=lambda x: x[1], reverse=True)

# 将词频写入文件
with open('freq.txt', 'w', encoding='utf-8') as f:
    for item in items:
        f.write(str(item)+'\n')
        if item[1] <= 2:  # 出现2次以下的不写入
            break

于是就得到了词频统计文件freq.txt

在这里插入图片描述

可以看到对于golang来说,面试中最常出现的考点是“项目”、“算法”以及“进程”等等(没用的词语太多了,可以通过设置一些停用词来去掉诸如“什么”,“一个”这些没有意义的词语)

如果想美观一点还可以弄成表格或者词云图之类的