python - 如何从多个网页中提取文本,其中某些页面的文本在不同的标签下?
问题描述
我正在尝试从此网址中提取所有成绩单 - https://fangj.github.io/friends/
我已经尝试了我的代码,但是
第 217-223 集没有完全提取。
第 302 集没有任何记录被提取。
第 224、921、1015 集(以及更多)每个对话没有一行。
等等。
如果我理解正确,许多网页的文本结构不同,这使我很难概括代码,除非我在这里遗漏了一些东西。
我的目标是从网页中获取文本,将剧集名称作为文件名的文本文件 - 即0101.txt
等0310.txt
,就像 url 结尾扩展名一样。现在我已经手动收集了它们ctrl+a + ctrl+c + ctrl+v
。我希望刮掉它,以便我可以自动化这个过程。现在,该替代方案就是pyautogui
用于此目的。但如果可能的话,我更喜欢网络抓取。如果存在,我对 python 中的其他库持开放态度。
代码
import requests
from bs4 import BeautifulSoup
url = "https://fangj.github.io/friends/"
page_content = requests.get(url, timeout=5)
page_html = BeautifulSoup(page_content.content, "html.parser")
list_of_links = page_html.findAll('a')
list_of_hrefs = []
for href in list_of_links:
if href.has_attr('href'):
list_of_hrefs.append(href.attrs['href'])
episode_nos = []
for link in list_of_hrefs:
episode_nos.append(link.split('/')[1].split('.')[0])
list_of_urls = []
for href in list_of_hrefs:
list_of_urls.append(url+href)
for episode_no, one_url in enumerate(list_of_urls):
episode_content = requests.get(one_url, timeout=5)
episode_html = BeautifulSoup(episode_content.content, "html.parser")
episode_dialogues = episode_html.findAll('p')
with open('../../data/raw/{}.txt'.format(episode_nos[episode_no]), 'w', encoding='utf-8') as file:
for text in episode_dialogues:
file.write(text.text.replace('\n', ' ') + '\n')
解决方案
您可以选择整个 HTML 标记文本以获取每个剧集链接中的所有内容,即select_one('html').text
. 这似乎容易多了。
您可以使用带有^
运算符的 css 属性 = 值选择器(状态值以 右侧的子字符串开头=
)来收集所有初始剧集链接,即[href^='season']
.
在拨打很多电话时,您可以重复使用与会话的连接。我相信多处理在这里也可能是一个好主意。
import requests
import pandas as pd
from bs4 import BeautifulSoup
import ftfy
session = requests.Session()
def makeSoup(url):
res = session.get(url,timeout=5)
res.raise_for_status()
soup_content = BeautifulSoup(res.content, "lxml")
for style in soup_content(["style"]):
style.decompose()
return soup_content
url = "https://fangj.github.io/friends/"
soup = makeSoup(url)
links = [url + link['href'] for link in soup.select("[href^='season']")]
results = [[link.split('season/')[1].split('.html')[0], makeSoup(link).select_one('html').text] for link in links]
df = pd.DataFrame(results)
for index, row in df.iterrows():
with open('data/' + row[0] + '.txt', 'w', encoding='utf-8') as file:
file.write(ftfy.fix_text(row[1]))
然后,您可以对检索到的文本执行您需要的操作。