【语言学习-python-爬虫】(2)从多个网页爬取文本

由 联环己烷 发布

前情提要:从零开始爬取一段指定文字

其实也没有多学什么东西,从多个网页爬取和单个也差不多吧……

获取目标网页链接

虽然说有剧情文本的页面并不多,手动列出来也可以,不过我们还是试着直接爬一下。

HTML里,a是链接的标签,那么只要用BeautifulSoup中的find_all来查找页面的相关链接,就能够得到含有剧情文本的页面了。当然我们还可以再精确定位定位。

先输出整个页面,可以发现含有剧情文本的页面位于memu-popout中:

s1.png

这些链接并不完整,但是相关类里还包含萌百的一些外部链接。所以可以用正则表达式来筛选出萌百内部链接。

#coding: utf-8

from bs4 import BeautifulSoup
from urllib import request
import re

file_path = 'D:/sources/'
base_url = 'https://zh.moegirl.org.cn/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF'
outfile=open('out.txt',"w",errors='ignore')


def main():
    req=request.Request(url=base_url)
    response=request.urlopen(req).read().decode()
    #print(response,file=outfile)
    soup=BeautifulSoup(response,'lxml')
    tables=soup.find_all('div',class_='menu-popout') #筛掉一些不在表格里的链接
    for table in tables:
        links=table.find_all('a',href=re.compile(r'/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF')) #筛选内部链接
        for link in links:
            res_url=link['href']
            print(res_url,end=' ',file=outfile)
            if(link.get('title')!=None):
                print(link['title'],file=outfile)
    


if(__name__=='__main__'):
    main()

输出来看看的话,还是有些没有剧情文本的额外页面没有筛掉,这似乎只能手动筛了。其中“异构体”的剧情文本不在活动词条主页面,再加上小活动全部处于同一个页面上,手动修订一下我们的链接名单,可以得到:

/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E5%BA%8F%E7%AB%A0 主线/序章
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E7%AC%AC%E4%B8%80%E6%88%98%E5%BD%B9 主线/第一战役
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E7%AC%AC%E4%BA%8C%E6%88%98%E5%BD%B9 主线/第二战役
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E7%AC%AC%E4%B8%89%E6%88%98%E5%BD%B9 主线/第三战役
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E7%AC%AC%E5%9B%9B%E6%88%98%E5%BD%B9 主线/第四战役
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E7%AC%AC%E9%9B%B6%E6%88%98%E5%BD%B9 主线/第零战役
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E7%AC%AC%E4%BA%94%E6%88%98%E5%BD%B9 主线/第五战役
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E7%AC%AC%E5%85%AD%E6%88%98%E5%BD%B9 主线/第六战役
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E7%AC%AC%E4%B8%83%E6%88%98%E5%BD%B9 主线/第七战役
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E7%AC%AC%E5%85%AB%E6%88%98%E5%BD%B9 主线/第八战役
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E7%AC%AC%E4%B9%9D%E6%88%98%E5%BD%B9 主线/第九战役
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E7%AC%AC%E5%8D%81%E6%88%98%E5%BD%B9 主线/第十战役
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E7%AC%AC%E5%8D%81%E4%B8%80%E6%88%98%E5%BD%B9 主线/第十一战役
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E7%AC%AC%E5%8D%81%E4%BA%8C%E6%88%98%E5%BD%B9 主线/第十二战役
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E7%AC%AC%E5%8D%81%E4%B8%89%E6%88%98%E5%BD%B9 主线/第十三战役
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2016%E5%B9%B4%E5%A4%8F%E5%AD%A3%E6%B4%BB%E5%8A%A8%E2%80%9C%E9%AD%94%E6%96%B9%E8%A1%8C%E5%8A%A8%E2%80%9D 限定作战/2016年夏季活动“魔方行动”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2017%E5%B9%B4%E5%86%AC%E5%AD%A3%E6%B4%BB%E5%8A%A8%E2%80%9C%E5%A4%B1%E6%B8%A9%E7%97%87%E2%80%9D 限定作战/2017年冬季活动“失温症”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2017%E5%B9%B4%E6%98%A5%E5%AD%A3%E6%B4%BB%E5%8A%A8%E2%80%9C%E9%AD%94%E6%96%B9%E8%A1%8C%E5%8A%A8PLUS%E2%80%9D 限定作战/2017年春季活动“魔方行动PLUS”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2017%E5%B9%B4%E8%81%94%E5%8A%A8%E6%B4%BB%E5%8A%A8%E2%80%9C%E7%8C%8E%E5%85%94%E8%A1%8C%E5%8A%A8%E2%80%9D 联动活动/2017年联动活动“猎兔行动”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2017%E5%B9%B4%E5%A4%8F%E5%AD%A3%E6%B4%BB%E5%8A%A8%E2%80%9C%E6%B7%B1%E5%B1%82%E6%98%A0%E5%B0%84%E2%80%9D 限定作战/2017年夏季活动“深层映射”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2017%E5%B9%B4%E8%81%94%E5%8A%A8%E6%B4%BB%E5%8A%A8%E2%80%9C%E7%8B%AC%E6%B3%95%E5%B8%88%E2%80%9D 联动活动/2017年联动活动“独法师”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2018%E5%B9%B4%E5%86%AC%E5%AD%A3%E6%B4%BB%E5%8A%A8%E2%80%9C%E5%A1%8C%E7%BC%A9%E7%82%B9%E2%80%9D 限定作战/2018年冬季活动“塌缩点”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2018%E5%B9%B4%E8%81%94%E5%8A%A8%E6%B4%BB%E5%8A%A8%E2%80%9C%E8%8D%A3%E8%80%80%E6%97%A5%E2%80%9D 联动活动/2018年联动活动“荣耀日”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2018%E5%B9%B4%E5%A4%8F%E5%AD%A3%E6%B4%BB%E5%8A%A8%E2%80%9C%E6%9C%89%E5%BA%8F%E7%B4%8A%E6%B5%81%E2%80%9D 限定作战/2018年夏季活动“有序紊流”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2019%E5%B9%B4%E5%86%AC%E5%AD%A3%E6%B4%BB%E5%8A%A8%E2%80%9C%E5%BC%82%E6%9E%84%E4%BD%93%E2%80%9D/%E6%88%98%E5%BD%B9%E5%89%A7%E6%83%85 限定作战/2019年冬季活动“异构体”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2019%E5%B9%B4%E8%81%94%E5%8A%A8%E6%B4%BB%E5%8A%A8%E2%80%9C%E7%93%A6%E5%B0%94%E5%93%88%E6%8B%89%E2%80%9D 联动活动/2019年联动活动“瓦尔哈拉”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2019%E5%B9%B4%E5%A4%8F%E5%AD%A3%E6%B4%BB%E5%8A%A8%E2%80%9C%E8%A3%82%E5%8F%98%E9%93%BE%E6%8E%A5%E2%80%9D 限定作战/2019年夏季活动“裂变链接”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2020%E5%B9%B4%E5%86%AC%E5%AD%A3%E6%B4%BB%E5%8A%A8%E2%80%9C%E5%81%8F%E6%8C%AF%E5%85%89%E2%80%9D 限定作战/2020年冬季活动“偏振光”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2020%E5%B9%B4%E8%81%94%E5%8A%A8%E6%B4%BB%E5%8A%A8%E2%80%9C%E6%A2%A6%E9%97%B4%E5%89%A7%E2%80%9D 联动活动/2020年联动活动“梦间剧”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF:2020%E5%B9%B4%E5%A4%8F%E5%AD%A3%E6%B4%BB%E5%8A%A8%E2%80%9C%E5%8F%8C%E8%81%94%E4%B9%B1%E6%95%B0%E2%80%9D 限定作战/2020年夏季活动“双联乱数”
/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF/%E8%8A%82%E5%BA%86%E9%99%90%E5%AE%9A%E4%BD%9C%E6%88%98  节庆活动

自多个页面下载文本

首先读入链接名单。直接使用file.read(),然后利用split函数分割即可得到页面名称和链接。

接下来打开几个链接分析一下。萌百上的格式有点不够统一,大部分页面上剧情文本和前情中存在一样的class内,但是“序章”中剧情文本是用'pre'标签的,“魔方行动”,“魔方行动plus”等几个活动页面没有那个class,就只能把表格文字都下载下来了,还会下载一些别的文本,不过影响也不大,优化方法我以后再研究一下吧……

还要注意一点,拼完整链接时写上zh-cn表示以简体中文访问,防止下载繁体版文本。

最后建立好输出目录,用get_text()输出即可。

#coding: utf-8

from bs4 import BeautifulSoup
from urllib import request
import re #正则表达式

file_path = 'D:/sources/'
base_url = 'https://zh.moegirl.org.cn/%E5%B0%91%E5%A5%B3%E5%89%8D%E7%BA%BF'
infile=open('in.txt','r',encoding='utf-8')

def read(): #读入名单
    lst=[]
    S=infile.read().split('\n')
    for s in S:
        lst.append(s.split())
    return lst

def get_texts(base_url):
    req=request.Request(url=base_url)
    response=request.urlopen(req).read().decode()
    soup=BeautifulSoup(response,'lxml')
    texts=soup.find_all('div',class_="mw-collapsible") #有这个div的情况,就不用下载额外文本了
    if(texts==[]): #没有的情况就下载所有表格,可能会有少量额外文本
        texts=soup.find_all('table',class_='mw-collapsible mw-collapsed wikitable')
    tmp=soup.find_all('pre') #这是“序章”的情况
    for t in tmp:
        texts.append(t)
    return texts

def main():
    lst=read()
    for L in lst:
        base_url='https://zh.moegirl.org.cn/zh-cn'+L[0];name=L[1] #拼凑链接,注意zh-cn
        texts=get_texts(base_url)
        print('----downloading: %s----'%(name))
        f=open(file_path+name+'.txt','w',errors='ignore') #下载文件位置
        for t in texts:
            print(t.get_text(),file=f)
        f.close()


if(__name__=='__main__'):
    main()

最后的结果:

s2.png


暂无评论

发表评论


京公网安备 11010802033049号