1.前言
我在今天还能更文,是不是很单身狗,可我也想尝尝这爱情的苦。越是在孤独的时候越是要战胜它,所以今天去买了一份慕课专栏,用买买买来解决孤独。
作为一个拥有几个、几十个、还是几百个粉丝的群主,怎么能忘了在苦海挣扎的你们呢?
这个专栏在网上已经是售出了7000 份,在这个小众群体中,这个销量已经是很高了,是47个专栏中最高的,可见写的确实很不错。
一线城市公司面试都会喜欢问一些源码的内容,尽管在工作上用的很少,不妨碍它存在,尝尝遭遇“面试造火箭,工作拧螺丝”的情况。但是我们要知道,即便是拧螺丝也是火箭的螺丝。
面试问的比较深入的问题,并不是为了难为你,而是看看你是否对一门语言有深层次的把握。
好比你熟悉了古今中外的历史,你会发现,这个世界的规律从来没变过。
废话这么多,那么说说今天的礼物吧。就是上面的这份专栏,我已经把内容转存成PDF。但是授之于鱼不如授之于渔,今天的分享一份Python代码,爬取网页html内容,保存到PDF后自(da)己(jia)看。
2.需求
爬取慕课网《面试官系统精讲Java源码及大厂真题》专栏的内容,以PDF形式保存到本地。
3.分析
- 这是付费内容,所以肯定会判断当前请求是否合法,所以爬虫中必须带着cookice的内容,让服务器知道这是你,否则会拒绝你的请求。
- 使用wkhtmltopdf 工具,需要到官网下载安装本地后可以用。
- 工具是将HTML页面转成PDF,第一个图是网页的内容,左边的目录是灵活的,但是下载到PDF中就没有效果,还不好看,所以直接把目录拿掉,达到效果是第二个。
- 代码中 html_template 就是拼装的模板,删除了不需要的内容,所以你需要知道一点前端的内容。
- 剩下的就是爬虫常用的几个库 requests ,BeautifulSoup ,json
- 源码贴在下面了仅供参考使用。没有使用 try except,生产中需要不住异常。
import os
import requests
from bs4 import BeautifulSoup
import json
import pdfkit
html_template = """
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet"
href="http://static.mukewang.com/static/css/??base.css,common/common-less.css?t=2.5,column/zhuanlanChapter-less.css?t=2.5,course/inc/course_tipoff-less.css?t=2.5?v=201911221436"
type="text/css"/>
<link href="http://moco.imooc.com/captcha/style/captcha.min.css" rel="stylesheet">
<link rel="stylesheet" href="http://www.imooc.com/static/moco/v1.0/dist/css/moco.min.css?t=201911221436" type="text/css" />
<link rel="stylesheet" href="http://www.imooc.com/static/lib/swiper/swiper-3.4.2.min.css?t=201911221436">
</head>
<body style="background:white;background-color:white">
<div class="main-con fixed">
<div class="right-content" style="padding-left:0px;">
<div class="container clearfix" style="display: block;">
<div class="center_con js-center_con l">
{content}
</div>
</div>
</div>
</div>
</body>
</html>
"""
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36',
'Cookie': 'sajssdk_2015_cross_new_user=1; Hm_lvt_f0cfcccd7b1393990c78efdeebff3968=1589958823; IMCDNS=0; imooc_isnew=1; imooc_isnew_ct=1589958822; imooc_uuid=79ba42d1-dba0-4c15-bcb4-59791dc988a9; last_login_username=liudrain@163.com; adv_#globalTopBanner_2911=1589958872594; PSEID=18bab2b6e29e505149c9bfed416f7aa4; loginstate=1; apsid=AwNjIwNzRjYjg4YmZkYzVmZWM1YWIzYTlhOTM4MTgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMzE5NjgyOQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsaXVkcmFpbkAxNjMuY29tAAAAAAAAAAAAAAAAAAAAADBhZjliMmRkYmUyZjJiM2FhNmExNmY3Mjc5YWMwNDI4LNnEXizZxF4=Zj; sensorsdata2015jssdkcross={"distinct_id":"3196829","first_id":"17230ee4b1167c-07bcf017e968db-376b4502-2073600-17230ee4b1298f","props":{"$latest_traffic_source_type":"引荐流量","$latest_search_keyword":"未取到值","$latest_referrer":"https://unitradeprod.alipay.com/acq/cashierReturn.htm?sign=K1iSL1GPeGbSvmIcCfvJFOlQnC344vkFZfgRwLbnwkpv%252FwlaJRev1UgxnMKwijyz5F%252FGw26TwRM%253D&outTradeNo=2005201517348565407335&pid=20888216223418"},"$device_id":"17230ee4b1167c-07bcf017e968db-376b4502-2073600-17230ee4b1298f"}; addQunTip47=true; Hm_lpvt_f0cfcccd7b1393990c78efdeebff3968=1589959225; cvde=5ec4d8a670b63-39',
'Host': 'www.imooc.com'
}
# 通过url获取到html保存到本地
def parse_url_to_html(url, name):
response = requests.get(url, headers=headers, timeout=30)
soup = BeautifulSoup(response.content, "html.parser")
body = soup.find_all(class_="article-con")[0]
html = str(body)
html = html_template.format(content=html)
html = html.replace("//img", "http://img")
html = html.replace("/static/img", "http://www.imooc.com/static/img")
html = html.replace("data-original", "src")
# html = html.replace('''alt="图片描述"''', '''alt="图片描述" style="height:60%"''')
with open("imooc/" name, 'w', encoding="utf-8") as f:
f.write(str(html))
return name
# html 转成pdf
def html_to_pdf(htmlname, pdfname):
options = {
'page-size': 'Letter',
'margin-top': '0',
'margin-right': '0',
'margin-bottom': '0',
'margin-left': '0',
'encoding': "UTF-8",
'no-outline': None,
'custom-header': [
('Accept-Encoding', 'gzip')
],
'outline-depth': 10,
}
config = pdfkit.configuration(wkhtmltopdf='d:\Program Files\wkhtmltopdf\bin\wkhtmltopdf.exe')
pdfkit.from_file("imooc/" htmlname, "imooc/" pdfname, configuration=config)
# pdfkit.from_url(url, "imooc/686.pdf", configuration=config)
def get_menu_url(url):
response = requests.get(url, headers=headers)
jsonobject = json.loads(response.text)
list = jsonobject['data']['list']
for i in list:
urllist = i['list']
for n in urllist:
title = str(n['title'])
title = title.replace("?", "")
title = title.replace("?", "")
title = title.replace("*", "")
print(title)
# restful 链接 47是课程的id article 后面是文章的id
url = "http://www.imooc.com/read/47/article/" (n['url'][-3:])
name = parse_url_to_html(url, title ".html")
html_to_pdf(name, title ".pdf")
os.remove("imooc/" name)
if __name__ == '__main__':
# url = "http://www.imooc.com/read/43/article/686"
# 获取慕课网上的专栏的目录的list,其实需要知道课程id即可
url = "http://www.imooc.com/read/cataloglist?column_id=47"
get_menu_url(url)
4.总结
你可以用生活中来验证所学的内容,生活处处可以python。
总体来讲,作为一个工具,python是个不错的万能胶。这样看起来,是不是比网页上爽多了,还可以分享呢。
上面的相关资料我已经分享在群里,谢谢大家的支持。
最后祝大家520快乐,能早日脱单。