您现在的位置是:首页 > 技术教程 正文

用 Python 爬取网页 PDF 和文档

admin 阅读: 2024-03-25
后台-插件-广告管理-内容页头部广告(手机)

目录

  • 1 爬取网页 PDF
    • 1.1 在日历控件中输入时间
    • 1.2 下载 PDF 文件
    • 1.3 selenium 访问网站被反爬限制封锁
    • 1.4 完整代码
  • 2 爬取网页文档
    • 2.1 遇到的问题
    • 2.2 完整代码
  • 3 一些资源推荐

1 爬取网页 PDF

以 https://reader.jojokanbao.cn/rmrb 上 PDF 的下载为例

1.1 在日历控件中输入时间

参考博客:selenium+Python(Js处理日历控件)
网页的日期框中可以直接输入日期
在这里插入图片描述
找到输入框对应的标签,根据 class name 进行内容清楚和输入(如果标签有 id 属性可以根据 id 进行输入框确定),代码如下

browser.find_element_by_class_name('el-input__inner').clear() browser.find_element_by_class_name('el-input__inner').send_keys('1976-10-09')
  • 1
  • 2

在这里插入图片描述
输入日期后需要回车才能刷新页面,使用 selenium 模拟键盘事件参考博客:selenium-模拟键盘事件(回车、删除、刷新等)
实现代码如下

from selenium.webdriver.common.keys import Keys browser.find_element_by_class_name('el-input__inner').send_keys(Keys.ENTER)
  • 1
  • 2
  • 3

1.2 下载 PDF 文件

使用 selenium 下载 PDF 文件参考博客:python selenium 下载pdf文件
需要将简单的 browser = webdriver.Chrome() 替换为如下代码

# PDF 文件保存路径 down_load_dir = os.path.abspath(".") options = webdriver.ChromeOptions() options.add_experimental_option("excludeSwitches", ['enable-automation']) prefs = { "download.default_directory": down_load_dir, "download.prompt_for_download": False, "download.directory_upgrade": True, "plugins.always_open_pdf_externally": True } options.add_experimental_option('prefs', prefs) options.add_argument("--disable-blink-features=AutomationControlled") browser = webdriver.Chrome(options=options)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

1.3 selenium 访问网站被反爬限制封锁

参考博客:python之selenium访问网站被反爬限制封锁解决方法
添加如下代码

browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { "source": """ Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) """ })
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

1.4 完整代码

from selenium import webdriver from selenium.webdriver.common.keys import Keys import time from bs4 import BeautifulSoup import os url = 'https://reader.jojokanbao.cn/rmrb' down_load_dir = os.path.abspath(".") options = webdriver.ChromeOptions() options.add_experimental_option("excludeSwitches", ['enable-automation']) prefs = { "download.default_directory": down_load_dir, "download.prompt_for_download": False, "download.directory_upgrade": True, "plugins.always_open_pdf_externally": True } options.add_experimental_option('prefs', prefs) options.add_argument("--disable-blink-features=AutomationControlled") browser = webdriver.Chrome(options=options) browser.execute_cdp_cmd("Page.addScriptToEvaluateOnNewDocument", { "source": """ Object.defineProperty(navigator, 'webdriver', { get: () => undefined }) """ }) browser.get(url) browser.find_element_by_class_name('el-input__inner').clear() browser.find_element_by_class_name('el-input__inner').send_keys('1976-10-09') # 输入完成后,敲击键盘上的回车键 browser.find_element_by_class_name('el-input__inner').send_keys(Keys.ENTER) time.sleep(5) data = browser.page_source # print(data) # 获取文档的下载链接 soup = BeautifulSoup(data) body = soup.find('div', attrs={'class': 'el-col el-col-24 el-col-xs-24 el-col-sm-12 el-col-md-12 el-col-lg-12 el-col-xl-12'}) link = body.find_all("a")[0].get("href") print(link) # 有了开始对 options 的设置,这一步可以直接下载 PDF 文档 browser.get(link) time.sleep(5) browser.close()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50

2 爬取网页文档

以 https://www.laoziliao.net/rmrb/ 上的文档下载为例

2.1 遇到的问题

整体实现思路和爬取小说(https://blog.csdn.net/mycsdn5698/article/details/133465660)的一样,实现过程中遇到了一些问题:
(1)BeautifulSoup 怎样获取标签间文本内容
获取标签的某个属性,例如 a 标签的 href 属性,代码如下

data = requests.get(url = url, headers = headers) data.encoding = 'UTF-8' soup = BeautifulSoup(data.text, 'html.parser') body = soup.find('div', attrs={'id': 'month_box'}) for item in body.find_all('a'): link = item.get("href") print(link)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

获取标签间的文本内容
如果标签属性较少,则可以使用正则提取,例子及其代码如下
在这里插入图片描述

findTitle = re.compile(r'

(.*?)

'
,re.S) for card in soup.find_all('div', class_="card mt-2"): # 提取标题 card_title = re.findall(findTitle, str(card))[0] print(card_title)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

如果标签属性较多,则可以参考博客:beautifulsoup怎样获取标签间文本内容,例子及其代码如下
在这里插入图片描述

data = requests.get(url = news_link, headers = headers) data.encoding = 'UTF-8' soup = BeautifulSoup(data.text, 'html.parser') for context in soup.find_all('div', class_="card mt-2"): # 提取标题 news_title = context.find('h2').string print(news_title)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

(2)将 br 标签替换为换行符
例子如下
在这里插入图片描述
方法一:使用 get_text()
缺点:br 标签会变成一些空格,而不是换行

for news_context in context.find_all('div', class_="card-body lh-lg"): tmp_context = news_context.get_text() print(tmp_context)
  • 1
  • 2
  • 3

方法二:参考博客 https://blog.csdn.net/u012587107/article/details/80543977
缺点:str(news_context) 的使用导致 div 标签出现,且
变成了

for news_context in context.find_all('div', class_="card-body lh-lg"): tmp_context = (str(news_context).replace('
'
,'\n')).replace('
'
,'\n') # str(news_context) 的使用导致 和 也出现了 tmp_context = (tmp_context.replace('','')).replace('','') # 新闻标题的第一行前是俩Tab,将其替换为四个空格 tmp_context = tmp_context.replace('  ',' ') print(tmp_context)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

2.2 完整代码

注意:ANSI 编码的文本在 kindle 打开会有部分乱码,UTF-8 编码的不会

import requests import re import time from bs4 import BeautifulSoup headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36'} findTitle = re.compile(r'

(.*?)

'
,re.S) url = "https://www.laoziliao.net/rmrb/1946-06" # 获取该月内所有日报的链接 data = requests.get(url = url, headers = headers) data.encoding = 'UTF-8' soup = BeautifulSoup(data.text, 'html.parser') body = soup.find('div', attrs={'id': 'month_box'}) for item in body.find_all('a'): link = item.get("href") # print(link) # 根据 link 创建每天报纸的 TXT # 提取最后一个斜杠后面的字符 last_slash_index = link.rfind("/") if last_slash_index != -1: TXT_name = link[last_slash_index + 1:] TXT_name = TXT_name.replace("-", "") print(TXT_name) # ansi 编码用 kindle 打开有乱码 with open("./TXTs/"+TXT_name+".txt", "w", encoding='utf-8') as f: # 访问每天的报纸 data = requests.get(url = link, headers = headers) data.encoding = 'UTF-8' soup = BeautifulSoup(data.text, 'html.parser') # 每一版的内容都放在 class="card mt-2" 的 div 中 for card in soup.find_all('div', class_="card mt-2"): # 提取标题 card_title = re.findall(findTitle, str(card))[0] f.write(card_title + '\n') # print(card_title) # 提取新闻链接 news = card.find_all('a') news_link = news[0].get('href') if "#" in news_link: index = news_link.index("#") news_link = news_link[:index] print(news_link) time.sleep(1) # 访问当天的每一版新闻,每一条新闻都放在 class="card mt-2" 的 div 中 data = requests.get(url = news_link, headers = headers) data.encoding = 'UTF-8' soup = BeautifulSoup(data.text, 'html.parser') for context in soup.find_all('div', class_="card mt-2"): # # 提取标题 # news_title = context.find('h2').string # print(news_title) # 提取新闻内容,存放在 class="card-body lh-lg" 的 div 中 for news_context in context.find_all('div', class_="card-body lh-lg"): # 把
换成换行符
tmp_context = (str(news_context).replace('
'
,'\n')).replace('
'
,'\n') # str(news_context) 的使用导致 和 也出现了 tmp_context = (tmp_context.replace('','')).replace('','') # 新闻标题的第一行前是俩Tab,将其替换为四个空格 tmp_context = tmp_context.replace('  ',' ') f.write(tmp_context + '\n') # print(tmp_context) f.write('\n\n')
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71

3 一些资源推荐

除了上述两个作为例子的网站,还有 时光印记经典珍藏系列,可以免费查看部分资料,全部资料的话是收费的。

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索
排行榜