zoukankan      html  css  js  c++  java
  • Python 3 爬虫-爬取我的博客园的所有博文列表

    描述

    该链接爬取的是作者在CSDN上写的博文,我就研究爬取一下我自己在博客园上的博文吧。
    这是我的博客园首页:http://www.cnblogs.com/wsygdb/default.html

    确定要提取的信息:
    1.标题
    2.发布日期
    3.文章链接
    4.浏览量
    5.评论量

    确认headers

    使用fiddler来查看访问我的博客园首页所需的报头:

    确认报头为:

    headers = {
        'Host': 'www.cnblogs.com',
        'Connection': 'keep-alive',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'Accept-Encoding': 'gzip, deflate',
        'Accept-Language': 'zh-CN,zh;q=0.9'
    }
    

    分析网页源代码

    获取网页源代码

    根据url和伪装的header获取网页源代码

    def getHtml(url,headers):
        request = urllib.request.Request(url=url,headers=headers)
        page = urllib.request.urlopen(request)
        html = page.read()
        return html
    

    调用时,报错:UnicodeDecodeError: 'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte

    我怀疑是不是程序获取的页面源码是经过压缩的,添加解压过程:
    解压

    def ungzip(data):
        try:
            print('正在解压...')
            data = gzip.decompress(data)
            print('解压完成')
        except:
            print('未压缩,无需解压')
        return data
    

    OK,问题完美解决

    提取博文信息

    博文需要提取两个信息:

    1. 文章链接、文章标题、发布时间、阅读数和评论数;
    2. “下一页”的链接;

    获取文章链接、文章标题、发布时间、阅读数和评论数

    如图,这是一篇文章的相关数据:

    			<div class="postTitle">
    				<a id="homepage1_HomePageDays_DaysList_ctl06_DayList_TitleUrl_0" class="postTitle2" href="http://www.cnblogs.com/wsygdb/p/7661220.html">解决:Invalid character found in the request target.The valid characters are defined in RFC 7230 and RFC3986</a>
    			</div>
    			<div class="postCon"><div class="c_b_p_desc">摘要: [toc] 背景 在将tomcat升级到7.0.81版后,发现系统的有些功能不能使用了,查询日志发现是有些地址直接被tomcat认为存在不合法字符,返回HTTP 400错误响应,错入信息如下: 原因分析 经了解,这个问题是高版本tomcat中的新特性:就是严格按照 RFC 3986规范进行访问解析,<a href="http://www.cnblogs.com/wsygdb/p/7661220.html" class="c_b_p_desc_readmore">阅读全文</a></div></div>
    			<div class="clear"></div>
    			<div class="postDesc">posted @ 2017-10-13 14:59 我是一个豆笔 阅读(62) 评论(0)  <a href ="https://i.cnblogs.com/EditPosts.aspx?postid=7661220" rel="nofollow">编辑</a></div>
    			<div class="clear"></div>
    

    获取文章的相关信息的正则表达式:文章链接、文章标题、发布时间、阅读数和评论数
    articleInfoRe = r'class="postTitle2".href="(.?)">(.?).?@.(.?).我是一个豆笔.?阅读((.?)).?评论((.?))'

    获取“下一页”的链接

    如图,这是“下一页”的页面源代码数据:

    <div class="topicListFooter"><div id="nav_next_page"><a href="http://www.cnblogs.com/wsygdb/default.html?page=2">下一页</a></div></div>
    

    对应的正则表达式为:
    isNextPage = r'href="(.*?)">下一页'

    此处对正则表达式做一个简要说明:
    1).
    ? 是一个固定的搭配,.和代表可以匹配任意无限多个字符,加上?表示使用非贪婪模式进行匹配,也就是我们会尽可能短地做匹配,以后我们还会大量用到 .? 的搭配。
    2)(.?)代表一个分组,在这个正则表达式中我们匹配了1个分组,在后面的遍历item中,item[0]就代表第一个(.?)所指代的内容,item[1]就代表第二个(.?)所指代的内容,以此类推。

    获取我的博客园的所有文章数据

    获取规则:
    分页获取我的博客园的所有的文章链接、文章标题、发布时间、阅读数和点赞数。
    匹配该页是否还有下一页,若有则继续获取下一页的数据,直到最后一页。

    这是整个程序代码:

    '''
    描述:博客园的文章列表爬虫(http://www.cnblogs.com/wsygdb/default.html),获取每篇文章的标题、发布日期、文章链接、浏览量和评论量。
    时间:2017.11.28
    作者:我是一个豆笔
    '''
    
    import urllib.request,sys,gzip,re
    print(sys.getdefaultencoding())
    
    headers = {
        'Host': 'www.cnblogs.com',
        'Connection': 'keep-alive',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/62.0.3202.94 Safari/537.36',
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'Accept-Encoding': 'gzip, deflate',
        'Accept-Language': 'zh-CN,zh;q=0.9'
    }
    
    # 判断是否还有下一页
    isNextPage = r'href="(.*?)">下一页</a></div></div>'
    
    # 获取文章的相关信息的正则表达式链接、文章标题、发布时间、阅读数和评论数
    articleInfoRe = r'class="postTitle2".href="(.*?)">(.*?)</a>.*?@.(.*?).我是一个豆笔.*?阅读((.*?)).*?评论((.*?))'
    
    url = 'http://www.cnblogs.com/wsygdb/default.html'
    
    # 根据url和伪装的header获取网页源代码
    def getHtml(url,headers):
        request = urllib.request.Request(url=url,headers=headers)
        page = urllib.request.urlopen(request)
        html = page.read()
        return html
    
    # 解压
    def ungzip(data):
        try:
            print('正在解压...')
            data = gzip.decompress(data)
            print('解压完成')
        except:
            print('未压缩,无需解压')
        return data
    
    html = getHtml(url,headers)
    data = ungzip(html).decode('utf-8')
    # print(data)
    
    allArticleInfo = []
    
    while True:
        # 获取当前页列表
        articleInfoCom = re.compile(articleInfoRe, re.S)  # 由于有换行的情况,使用DOTALL模式匹配
        articleInfos = re.findall(articleInfoCom, data)
        for articleInfo in articleInfos:
            allArticleInfo.append(articleInfo)
    
        # 按照是否有“下一页”来判断是否获获取完了所有页
        isNextPageCom = re.compile(isNextPage) 
        nextPages = re.findall(isNextPageCom, data)
        if len(nextPages)>=1:
            nextPage = nextPages[0]
            print(nextPage)
            if nextPage != "":
                url = nextPage
                html = getHtml(url, headers)
                data = ungzip(html).decode('utf-8')
                continue
            else:
                break
        else:
            break
    
    # 循环输出
    for articleInfo in allArticleInfo:
        print(articleInfo)
    
    
  • 相关阅读:
    css定位
    css遗漏
    php字符操作
    php类于对象
    php数组的操作
    php基础
    javascript显式类型的转换
    【模板】并查集
    图论三种做法:朴素版Dijkstra、堆优化(优先队列)Dijkstra、spfa(队列优化版Bellman-Ford)
    二分之一网打尽
  • 原文地址:https://www.cnblogs.com/wsygdb/p/7942982.html
Copyright © 2011-2022 走看看