1 importurllib.request as ure2 importre3 importurllib.parse4 from delayed importWaitFor5 importlxml.html6 importos7 importdocx8 #下载网页并返回HTML(动态加载的部分下载不了)
9 def download(url,user_agent='FireDrich',num=2):10 print('下载:'+url)11 #设置用户代理
12 headers = {'user_agent':user_agent}13 request = ure.Request(url,headers=headers)14 try:15 #下载网页
16 html =ure.urlopen(request).read()17 excepture.URLError as e:18 print('下载失败'+e.reason)19 html=None20 if num>0:21 #遇到5XX错误时,递归调用自身重试下载,最多重复2次
22 if hasattr(e,'code') and 500<=e.code<600:23 return download(url,num-1)24 returnhtml25 #seed_url传入一个url,例如https://www.cnblogs.com/
26 #link_regex传入一个正则表达式
27 #函数功能:提取和link_regex匹配的所有网页链接并下载
28 deflink_crawler(seed_url, link_regex):29 html =download(seed_url)30 crawl_queue =[]31 #迭代get_links()返回的列表,将匹配正则表达式link_regex的链接添加到列表中
32 for link inget_links(html):33 ifre.match(link_regex, link):34 #拼接https://www.cnblogs.com/ 和 /cate/...
35 link =urllib.parse.urljoin(seed_url, link)36 #不在列表中才添加
37 if link not incrawl_queue:38 crawl_queue.append(link)39 x =040 #调用WaitFor的wait()函数,下载限速,间隔小于2秒则等待,直到间隔等于2秒才继续下载(大于5秒则直接继续下载)
41 waitFor = WaitFor(2)42 #下载crawl_queue中的所有网页
43 whilecrawl_queue:44 #删除列表末尾的数据
45 url =crawl_queue.pop()46 waitFor.wait(url)47 html =download(url)48 tree = lxml.html.fromstring(html) #解析HTML为统一的格式
49 title = tree.xpath('//a[@id="cb_post_title_url"]') #获取标题
50 the_file = tree.xpath('//div[@id="cnblogs_post_body"]/p') #获取正文内容
51 pre = tree.xpath('//pre') #获取随笔代码部分(使用博客园自带插入代码功能插入的)
52 img = tree.xpath('//div[@id="cnblogs_post_body"]/p/img/@src') #获取图片
53 #修改工作目录
54 os.chdir('F:\Python\worm\博客园文件')55 #创建一个空白新的Word文档
56 doc =docx.Document()57 #添加标题
58 doc.add_heading(title[0].text_content(), 0)59 for i inthe_file:60 #将每一段的内容添加到Word文档(p标签的内容)
61 doc.add_paragraph(i.text_content())62 #将代码部分添加到文档中
63 for p inpre:64 doc.add_paragraph(p.text_content())65 #将图片添加到Word文档中
66 for i inimg:67 ure.urlretrieve(i, '0.jpg')68 doc.add_picture('0.jpg')69 #截取标题的前8位作为Word文件名
70 filename = title[0].text_content()[:8] + '.docx'
71 #保存Word文档
72 #如果文件名已经存在,将文件名设置为title[0].text_content()[:8]+ str(x).docx,否则将文件名设置为filename
73 if str(filename) in os.listdir('F:\Python\worm\博客园文件'):74 doc.save(title[0].text_content()[:8] + str(x) + '.docx')75 x += 1
76 else:77 doc.save(filename)78 #传入html对象,以列表形式返回所有链接
79 defget_links(html):80 #使用正则表达式提取html中所有网页链接
81 webpage_regex = re.compile(']+href=["\'](.*?)["\']',re.IGNORECASE)82 html = html.decode('utf-8')83 #以列表形式返回所有网页链接
84 returnwebpage_regex.findall(html)85
86 link_crawler('https://www.cnblogs.com/cate/python/','.*/www.cnblogs.com/.*?\.html$')