使用Selenium Chrome Driver在2024年高效爬取网页PDF文件指南
#记录下第一次使用爬虫进行网页pdf爬取过程和踩坑记录#
1.目的
第一次做分析,想要在网上搜寻相关的研究报告之类的,但是总是有很多无关的链接文件或者不完整的引流链接,想到一般来说这种报告都是pdf居多,所以直接选择批量爬取.pdf文件再进行筛选会不会更有效率,于是直接开干。最终根据以下三个文章合并起来完成了小白的爬虫第一次。以下是本文的参考链接:
爬虫参考:2023最新使用python爬虫爬取全网.pdf网址并下载需要的pdf文件资源(可设置搜索keyword)!!!_如何通过爬虫下载一个网页里面的文档文件-CSDN博客
安装chrome driver参考:Selenium安装WebDriver最新Chrome驱动(含116/117/118/119)_chromedriver 119-CSDN博客
使用selenium打开浏览器报错 chromedriver‘ executable needs to be in PATH_chromedriver' executable needs to be in path.-CSDN博客
2.爬虫前提
2.1查看chrome浏览器版本
打开chrome浏览器,输入以下代码:
chrome://version/
这里可以看到我们的版本是126开头且chrome的路径也出来了。
2.2下载对应版本的chrome driver
那么我们就前往官网下载对应的driver。点击这里,就会看到这样一个界面:
点击stable,去选择和我们系统对应的 版本,这里我们是windows,win32既可以在32也可以在64环境使用,复制链接右键选择转到就可以下载了。
2.3移动chrome drive至python环境
下载好了之后就进行解压,然后就要去查询到我们python路径了,具体方法如下:点击“文件”->“设置”->“python解释器”->虚字路径。找到之后我们把chrome drive直接复制到该路径下的scripts问价夹下即可。这样就算完成了,也不需要加什么环境变量了。
2.4添加selenium标准库
因为刚开始我们是没有这个库的,所以加上代码也会是报错的,所以需要按以下步骤在终端下载:
pip install selenium
这里我已经是下载好了所以只是做演示,注意!!!如果后续仍然报错说缺少哪个模块一样采取以下命令下载补全:
pip install {模块名}
2.5测试
用以下测试代码即可,注意的是:
chromedriver_path = r"D:\Anaconda3\Scripts\chromedriver.exe"这里面的路径要改为自己计算机下对应的chromedrive路径。
from selenium import webdriver
chromedriver_path = r"D:\Anaconda3\Scripts\chromedriver.exe"
driver = webdriver.Chrome(chromedriver_path)
# 登录百度
def main():
driver.get("https://baidu.com/")
if __name__ == '__main__':
main()
效果应该是这样的 :
3.爬虫代码
3.1爬取链接
import urllib.parse # pip install urllib3==1.26.2
from selenium import webdriver # pip install selenium==3.141.0
from selenium.webdriver.common.keys import Keys
from bs4 import BeautifulSoup
import time
def scrape_pages(keyword, save_path, total_pages):
num = 0
driver = webdriver.Chrome()
for i in range(total_pages):
page = 10 * i + 1
url = f'https://www.bing.com/search?q={urllib.parse.quote(keyword)}&first={page}'
driver.get(url)
elem = driver.find_element_by_tag_name("body")
no_of_pagedowns = 15
while no_of_pagedowns:
elem.send_keys(Keys.PAGE_DOWN)
time.sleep(0.2)
no_of_pagedowns -= 1
html = driver.page_source
soup = BeautifulSoup(html, 'html.parser')
# 获取所有 h2 元素
h2_elements = soup.find_all('h2')
with open(save_path, 'a', encoding='utf-8') as f:
for h2 in h2_elements:
a_tag = h2.find('a') # 找到 h2 下的 a 标签
if a_tag and 'href' in a_tag.attrs: # 确保 a 标签存在并包含 href 属性
href = a_tag['href'] # 获取 href 属性的值
f.write(href + '\n')
num += 1
print(f"已保存{i + 1}页,共保存了{num}个网址")
driver.quit()
print(f"爬取完成,共保存了{num}个网址")
# 爬取200页
keyword = "小红书 filetype:pdf"
save_path = r"E:\xiaohongshu.txt"
total_pages = 10
scrape_pages(keyword, save_path, total_pages)
这里要注意的是
keyword = "小红书 filetype:pdf" save_path = r"E:\xiaohongshu.txt" total_pages = 10 scrape_pages(keyword, save_path, total_pages)keyword指的是你希望搜索的关键词,save_path是在自己电脑下保存的路径也是要自己创建修改的,total_pages指的是你要爬多少页的结果。
3.2下载pdf文件
import os
import requests
from urllib.parse import urlparse
from retry import retry
import urllib3
import re
urllib3.disable_warnings()
@retry(tries=3, delay=1, backoff=2)
def download_file(pdf_url, output_path):
response = requests.get(pdf_url, verify=False, stream=True)
content_disposition = response.headers.get('content-disposition')
if content_disposition:
filename = re.findall("filename=(.+)", content_disposition)
if filename:
output_path = os.path.join(output_path, filename[0])
with open(output_path, 'wb') as file:
for chunk in response.iter_content(chunk_size=1024):
if chunk:
file.write(chunk)
def download_pdfs_from_file(input_file, output_dir, error_file, start_from=1):
# 创建输出目录
os.makedirs(output_dir, exist_ok=True)
# 创建一个集合用于存放唯一的链接,去重
unique_urls = set()
# 读取文本文件中的所有行,并记录原始索引位置
with open(input_file, 'r', encoding='utf-8') as file:
lines = file.readlines()
for line in lines:
if '.pdf' in line:
unique_urls.add(line.strip())
# 获取PDF文件数量
total_pdfs = len(unique_urls)
unique_urls = list(unique_urls)
# 从指定位置开始下载PDF文件
for idx in range(start_from - 1, total_pdfs):
pdf_url = unique_urls[idx]
try:
# 下载PDF文件并保存至输出目录
print(f'Downloading file {idx + 1}/{total_pdfs}: {pdf_url}')
parsed_url = urlparse(pdf_url)
filename = os.path.basename(parsed_url.path)
output_path = os.path.join(output_dir, filename)
download_file(pdf_url, output_path)
print(f'\nDownloaded {pdf_url}')
except Exception as e:
# 输出错误信息至指定文件
print(f'\nFailed to download {pdf_url}: {str(e)}')
with open(error_file, 'a', encoding='utf-8') as err_file:
err_file.write(f'{pdf_url}\n')
finally:
pass
# 设定输入文件路径、输出目录路径和错误输出文件路径,并指定开始下载的位置
input_file_path = r"E:\xiaohongshu.txt"
output_directory = r"E:\资料\小红书\pdf" # 桌面创建pdf文件夹
error_output_file = r"E:\资料\小红书\pdf\false-url.txt" # 下载失败的url,可手动下载补充
start_download_from = 1 # 从第几个url开始
# 调用函数下载PDF文件,传入开始下载的位置参数和错误输出文件路径
download_pdfs_from_file(input_file_path, output_directory, error_output_file, start_from=start_download_from)
这里要注意的仍然是路径问题,input_file_path是输入文件的路径,也就是上面爬取链接路径保存下来的那个txt文件。output_directory指的是下载下来的pdf要存放的文件夹的路径。error_output_file相当于异常处理,把下载失败的链接名记录下来。
input_file_path = r"E:\xiaohongshu.txt" output_directory = r"E:\资料\小红书\pdf" # 桌面创建pdf文件夹 error_output_file = r"E:\资料\小红书\pdf\false-url.txt" # 下载失败的url,可手动下载补充
总结
以上就是一个简单的爬取pdf的方法过程了,具体实践后,会发现有可能下载到完全不相关的文件,这个就需要在进行具体筛选了,也可以在代码层面进行改进。也的确省下了不少的时间去搜索。
作者:摆烂牛杂