起因
由于以前的博客文章在电脑重装的时候全没了,直接 cv 战士难免太过麻烦,正好好久没有写 python 了,于是决定写一个爬虫来爬取文章并且生成 md 文档
分析
使用的技术和库
这里使用 python + BeautifulSoup4(网页装载与解析) + urllib(发起请求) + codecs(写入文件)
主页
我们来看看主页,一篇文章的位置
再来看看所有文章是怎么分布的
这简直就是最简单的 list 结构嘛
分页
文章不可能就只有一页,所以对分页的研究就体现在分页的 url 上,这样我们就能狗一次爬到底
看看第二页的url
推断一下,第 6 页应该是 http://wintersmilesb101.online/page/6
果然没错
那么看看第一页是否可以写成 http://wintersmilesb101.online/page/1 呢?
说明首页需要特殊处理,即 http://wintersmilesb101.online
抓取页面大小
页面大小的 dom 结构如下
可以看到,这几个 页面 index 的 class 是一致的,所以我们需要通过 BeautifulSoup 来选中上一个元素(这里可以看出上一个是这个结构中唯一的),或者是通过 BeautifulSoup 的 select 方法选中 class = page-number 的元素列表,最后一个即为 pageSize 的元素
文章信息
我们需要哪些文章信息?
由于我们这里是使用的 hexo 来构建的博客,所以要按照他的规则来,一般来说我们需要如下结构
---
title: Python3.7 爬虫(二)使用 Urllib2 与 BeautifulSoup 抓取解析网页
date: 2017-04-08
date: 2017-04-09
categories:
- 爬虫
- Python 爬虫
tags: - Python3
- 爬虫
- Urllib2
- BeautifulSoup4
---
这些信息,除了 标签,我们都可以在 文章列表页面就获取到了,如下:
当然这些信息,正文也页都有,正文页的链接,我们可以在 title 的位置获取到,与网站基础 url 拼接就可以获取到最终链接,不过有些 url 中有中文,因此我们需要使用 urllib.request.quote(link) 来把链接中的中文编码成 url 中的正确编码,这里会把 : 也转码了,转换成 %3A 因此,转换之后,我们还需要还原 %3A 为 :
正文的转换
正文就直接通过 获取到 class = post-body的元素,然后遍历子元素(通过 children 属性,注意 type 为 bs4.element.NavigableString 的元素,是无效元素,需要跳过),然后根据,html 与 markdown 的对应关系来转换成对应的 markdown 写法,不过在 BeautifulSoup 中还是有不少的坑点,这里代码中注释写的很清楚,就不赘述了
实现
import urllib.request
from bs4 import BeautifulSoup
import bs4
import re
import xlwt
import os
import codecs
filePath = r"H:/GIT/Blog/WinterSmileSB101/source/_posts/old/"
url = "http://wintersmilesb101.online"
user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
req = urllib.request.Request(url, headers={
'User-Agent': 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)'
})
print('发送 页面网络请求')
response = urllib.request.urlopen(req)
content = response.read().decode('utf-8')
# output content of page
#print(content)
soup = BeautifulSoup(content, "lxml")
# 获取页面数量
spans = soup.select('span.space')
pageHref = spans[spans.__len__()-1].nextSibling['href']
# get total num
pageNum = int(pageHref.split('/')[2</