目标页面:
我们需要用到的库:
import pdfkit
import requests
import parsel
相关模块可pip安装
分析页面结构
大概浏览以下页面,tags页面中包含了所有文章,不存在分页情况,这样就省去一步了。
F12打开开发者工具,查看页面源码,我们看到一个标签列表。
打开列表中的一个就会发现,该标签下的文章。
ctrl + shift +c ,选择 tags 页面中的文章标题 ”使用github个人博客“,我们看到了文章标题,链接以及class。
但是这里的链接只有后半部分,所以我们需要自己补全url
爬取每一篇文章的URL
实现代码
这里需要掌握 css选择器。(本人是初学者,所以下面内容如果存在错误之处,欢迎指出!)
需要注意的是,当页面结构发生改变时,css选择器对应的代码就要改变!
经过分析 文章的url 属于 post-preview 类,且位于a标签中,所以提取href的内容
selector.css('.post-preview a ::attr(href)').getall()
源码:
import requests
import pdfkit
import parsel
# 目标url
url = "https://yanmie-art.github.io/tags/"
# 文章url 前缀
url0 = "https://yanmie-art.github.io"
response = requests.get(url=url)
# 将网页变成选择器
selector = parsel.Selector(response.text)
# 爬取每篇文章的url(不完整)
urls1 = selector.css('.post-preview a ::attr(href)').getall()
# 爬取每篇文章的title
# titles = selector.css('.post-title::text').getall()
for url1 in urls1:
# 补全文章url
article_url = url0 + url1
# 打印验证
print(article_url)
爬取文章标题以及内容
爬取到每一篇文章的URL后,我们爬出每篇文章的标题和内容
同样分析页面结构,获得标题位置和内容位置
对于标题和内容的提取解析,同样使用css选择器,下面直接附上源码:
实现代码:
import requests
import pdfkit
import parsel
# 目标url
url = "https://yanmie-art.github.io/tags/"
# 文章url 前缀
url0 = "https://yanmie-art.github.io"
response = requests.get(url=url)
# 将网页变成选择器
selector = parsel.Selector(response.text)
# 爬取每篇文章的url(不完整)
urls1 = selector.css('.post-preview a ::attr(href)').getall()
# 爬取每篇文章的title
# titles = selector.css('.post-title::text').getall()
for url1 in urls1:
# 补全文章url
article_url = url0 + url1
# print(article_url)
# 请求文章url
response = requests.get(url=article_url)
selector = parsel.Selector(response.text)
# 获取文章标题,class="post-heading",h1标签,获取text
title = selector.css('.post-heading h1 ::text').getall()
# 过滤文章标题中不合法的字符,保证以文章标题为名存储为PDF时不报错
title = title[0]
title = title.replace('.', '')
title = title.replace('?', '')
title = title.replace('\'', '')
title = title.replace('"', '')
title = title.replace('/', '')
title = title.replace('\\', '')
# 获取文章内容
content = selector.css('.post-container').get()
# 打印验证
print(title)
print("*"*40)
print(content)
print("*"*40)
以标题名存储为PDF格式
现在所看到的返回的内容结果,除了标题是咱们需要的那样,但是内容还是网页数据。
咱们只需要把html改成PDF格式
wkhtmltopdf.exe 工具
有了这个小工具就可以将html格式改为PDF格式,直接上源码
完整代码:
import requests
import pdfkit
import parsel
# 目标url
url = "https://yanmie-art.github.io/tags/"
# 文章url 前缀
url0 = "https://yanmie-art.github.io"
html_str = """
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
{article}
</body>
</html>
"""
response = requests.get(url=url)
# 将网页变成选择器
selector = parsel.Selector(response.text)
# 爬取每篇文章的url(不完整)
urls1 = selector.css('.post-preview a ::attr(href)').getall()
# 爬取每篇文章的title
# titles = selector.css('.post-title::text').getall()
for url1 in urls1:
# 补全文章url
article_url = url0 + url1
# print(article_url)
# 请求文章url
response = requests.get(url=article_url)
selector = parsel.Selector(response.text)
# 获取文章标题,class="post-heading",h1标签,获取text
title = selector.css('.post-heading h1 ::text').getall()
# 过滤标题的非法字符,保证以标题名存储时正确
title = title[0]
title = title.replace('.', '')
title = title.replace('?', '')
title = title.replace('\'', '')
title = title.replace('"', '')
title = title.replace('/', '')
title = title.replace('\\', '')
# 获取文章内容
content = selector.css('.post-container').get()
# 打印验证
# print(title)
# print(content)
# print("*"*40)
# 转换格式
html = html_str.format(article=content)
# 写入html文件
with open(f'{title}.html', mode='w', encoding='utf-8') as f:
f.write(html)
print('{}已下载完成'.format(title))
# exe 文件存放的路径
config = pdfkit.configuration(wkhtmltopdf='D:\\wkhtmltox\\wkhtmltopdf\\bin\\wkhtmltopdf.exe')
# 报错:由于网络错误,以代码 1 退出:ProtocolUnknownError
# 解决方法:https://githubmate.com/repo/HAKSOAT/EpubToPdf/issues/3
options = {
"enable-local-file-access": None,
"quiet": ""
}
# 把 html 通过 pdfkit 变成 pdf 文件
pdfkit.from_file(f'{title}.html', f'{title}.pdf', configuration=config, options=options)