使用Python提取某CSDN博客的全部文章, 并转换为本地网页(例如一些连接, 是http网页的, 要转成本地的.). (成功提取后可以使用CHM工具把整个博客压成chm文件). 这里以我自己的博客http://blog.csdn.net/bagboy_taobao_com 为目标.
1.1 我这里只按照博客中两种方式提取文章: 文章分类和文章存档.
图1
2. 目标是文章内容, 有了内容后, 怎样显示就可以随意了, 不一定按照博客原来的显示, 当然按照原来的显示也可以.
3. 后续可以把数据添加到数据库保存等等等.....
1. 从网站抓取博客得到HTML字符串.
2. 分析HTML字符串, 提取需要的数据.
3. 提取得到后的数据再转换为本地的数据.
4. 难点: 分析HTML(因为对HTML不太熟悉); 如何转换成本地数据; 网页上的脚本JS可能也有难度; 还有DTD等.
使用浏览器查看http://blog.csdn.net/bagboy_taobao_com 的HTML并保存为Index.html(保存的格式必须为UTF8, 否则会乱码). 双击打开Index.html, 可以正确显示. OK, 可以用文本打开分析.
<div id="panel_Category" class="panel"> <ul class="panel_head"><span>文章分类</span></ul> <ul class="panel_body"> <li><a href="http://blog.csdn.net/bagboy_taobao_com/article/category/600202">ATL/WTL</a><span>(13)</span></li> <li><a href="http://blog.csdn.net/bagboy_taobao_com/article/category/623494">Boost</a><span>(3)</span></li> <li><a href="http://blog.csdn.net/bagboy_taobao_com/article/category/758331">C++模板</a><span>(3)</span></li> ... <li><a href="http://blog.csdn.net/bagboy_taobao_com/article/category/1502669">大数据</a><span>(0)</span></li> </ul> </div>
有什么特点? 那就是http://blog.csdn.net/bagboy_taobao_com/article/category/ , 判断到超连接有这串字符的就是一个分类.
<div id="panel_Archive" class="panel"> <ul class="panel_head"><span>文章存档</span></ul> <ul class="panel_body"> <div id="archive_list"> <!--归档统计--> <li><a href="http://blog.csdn.net/bagboy_taobao_com/article/month/2013/11">2013年11月</a><span>(2)</span></li> <li><a href="http://blog.csdn.net/bagboy_taobao_com/article/month/2013/10">2013年10月</a><span>(19)</span></li> ...... <li><a href="http://blog.csdn.net/bagboy_taobao_com/article/month/2008/11">2008年11月</a><span>(6)</span></li> </div> </ul> </div>
有什么特点? 那就是http://blog.csdn.net/bagboy_taobao_com/article/month/ , 判断到超连接有这串字符的就是一个存档.
#!/usr/bin/env python # coding=utf-8 # Python 2.7.3 # 获取博客文章分类列表和文章存档列表 # File: GetCategoryAndMonth.py import urllib2 import HTMLParser import httplib # from HTMLParser import HTMLParser class CHYGetCategoryAndMonth(HTMLParser.HTMLParser): def __init__(self, type, list): ''' type : 0 提取分类列表, 1 提取文章存档 ''' HTMLParser.HTMLParser.__init__(self) # 调用父类的构造函数, 这里调用时有self的 self.type = type self.ok = False self.listItem = ["", ""] self.list = list def handle_starttag(self, tag, attrs): if "a" == tag : for (variable, value) in attrs : if False == self.ok and (0 == self.type and variable == "href" and value.startswith("http://blog.csdn.net/bagboy_taobao_com/article/category/")) or (1 == self.type and variable == "href" and value.startswith("http://blog.csdn.net/bagboy_taobao_com/article/month/")): self.ok = True self.listItem[0] = value def handle_data(self, data): if True == self.ok: self.ok = False self.listItem[1] = data self.list.append(self.listItem) ''' # 测试代码 if __name__ == '__main__': conn = httplib.HTTPConnection("blog.csdn.net") # 要模拟成IE发送, 否则CSDN不接受Python的请求 user_agent = 'Mozilla/4.0 (compatible; MSIE 5.5; Windows NT)' headersP = { 'User-Agent' : user_agent } conn.request(method = "GET", url = "/bagboy_taobao_com", headers = headersP) r1 = conn.getresponse() # 获得响应 htmlByte = r1.read() # 获得HTML htmlStr = htmlByte.decode("utf8") # 需要转换成utf8编码, 否则分析异常 list = [] my = CHYGetCategoryAndMonth(0, list) my.feed(htmlStr) print(list) '''
遇到的异常情况:
1. CSDN不接受Python的请求, 所以需要模拟IE请求..
2. 得到的HTML文本需要转换为utf8 (htmlStr = htmlByte.decode("utf8")), 否则HTMLParser分析会出错.