• 爬取贴吧页面


    Get方式

    GET请求一般用于我们向服务器获取数据,比如说,我们用百度搜索传智播客https://www.baidu.com/s?wd=传智播客

    浏览器的url会跳转成如图所示:

    https://www.baidu.com/s?wd=%E4%BC%A0%E6%99%BA%E6%92%AD%E5%AE%A2

    在其中我们可以看到在请求部分里,http://www.baidu.com/s? 之后出现一个长长的字符串,其中就包含我们要查询的关键词传智播客,于是我们可以尝试用默认的Get方式来发送请求。

    from urllib import request, parse    # parse负责url编码处理
    
    url = "http://www.baidu.com/s"
    word = {"wd":"传智播客"}
    word = parse.urlencode(word)  #转换成url编码格式(字符串)
    newurl = url + "?" + word    # url首个分隔符就是 ?
    
    headers={ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.103 Safari/537.36"}
    
    req = request.Request(newurl, headers=headers)
    
    response = request.urlopen(req)
    
    print(response.read())

    批量爬取贴吧页面数据

    首先我们创建一个python文件, tiebaSpider.py,我们要完成的是,输入一个百度贴吧的地址,比如:

    百度贴吧LOL吧第一页:http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=0

    第二页: http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=50

    第三页: http://tieba.baidu.com/f?kw=lol&ie=utf-8&pn=100

    发现规律了吧,贴吧中每个页面不同之处,就是url最后的pn的值,其余的都是一样的,我们可以抓住这个规律。

    简单写一个小爬虫程序,来爬取百度LOL吧的所有网页。
    • 先写一个main,提示用户输入要爬取的贴吧名,并用 urllib.parse.urlencode()进行转码,然后组合url,假设是lol吧,那么组合后的url就是:http://tieba.baidu.com/f?kw=lol
    # 模拟 main 函数
    if __name__ == "__main__":
    
        kw = input("请输入需要爬取的贴吧:")
        # 输入起始页和终止页,str转成int类型
        beginPage = int(input("请输入起始页:"))
        endPage = int(input("请输入终止页:"))
    
        url = "http://tieba.baidu.com/f?"
        key = urllib.parse.urlencode({"kw" : kw})
    
        # 组合后的url示例:http://tieba.baidu.com/f?kw=lol
        url = url + key
        tiebaSpider(url, beginPage, endPage)
    • 接下来,我们写一个百度贴吧爬虫接口,我们需要传递3个参数给这个接口, 一个是main里组合的url地址,以及起始页码和终止页码,表示要爬取页码的范围。
    def tiebaSpider(url, beginPage, endPage):
        """
            作用:负责处理url,分配每个url去发送请求
            url:需要处理的第一个url
            beginPage: 爬虫执行的起始页面
            endPage: 爬虫执行的截止页面
        """
    
    
        for page in range(beginPage, endPage + 1):
            pn = (page - 1) * 50
    
            filename = "第" + str(page) + "页.html"
            # 组合为完整的 url,并且pn值每次增加50
            fullurl = url + "&pn=" + str(pn)
            #print(fullurl)
    
            # 调用loadPage()发送请求获取HTML页面
            html = loadPage(fullurl, filename)
            # 将获取到的HTML页面写入本地磁盘文件
            writeFile(html, filename)
    • 我们已经之前写出一个爬取一个网页的代码。现在,我们可以将它封装成一个小函数loadPage,供我们使用。
    def loadPage(url, filename):
        '''
            作用:根据url发送请求,获取服务器响应文件
            url:需要爬取的url地址
            filename: 文件名
        '''
        print("正在下载" + filename)
    
        headers = {"User-Agent": "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}
    
        req = urllibrequest.Request(url, headers = headers)
        response = request.urlopen(req)
        return response.read()
    • 最后如果我们希望将爬取到了每页的信息存储在本地磁盘上,我们可以简单写一个存储文件的接口。
    def writeFile(html, filename):
        """
            作用:保存服务器响应文件到本地磁盘文件里
            html: 服务器响应文件
            filename: 本地磁盘文件名
        """
        print "正在存储" + filename
        with open(filename, 'w', encoding='utf-8') as f:
            f.write(html)
        print "-" * 20
    

    完整代码:

    from urllib import request, parse
    import sys
    
    
    def loadPage(url, filename):
        """
        作用: 根据url发送请求, 获取服务器相应文件
        url: 需要爬取的url地址
        """
        print("正在下载" + filename)
        headers = {
            "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_8; en-us) AppleWebKit/534.50 (KHTML, like Gecko) Version/5.1 Safari/534.50"
        }
        req = request.Request(url, headers=headers)
        # 获得系统的编码
        type = sys.getfilesystemencoding()
        # 设置爬出内容的编码
        print(type)
        # ************************************************
        html = request.urlopen(req).read().decode(type)
        # ************************************************
        print(html)
        return html
    
    
    def writePage(html, filename):
        """
        作用: 将html内容写入到本地
        html: 服务器相应文件内容
        """
        print("正在保存" + filename)
        # ***********************************************
        with open(filename, "w", encoding="utf-8") as f:
            # ***********************************************
            f.write(html)
        print("*" * 30)
    
    
    def tiebaSpider(url, bingenPage, endPage):
        """
        作用: 爬虫爬虫调度器, 负责组合处理每一个页面的url
        url: 贴吧url的前部分,
        beginPage: 起始页
        endPage: 终止页
        """
        for page in range(beginPage, endPage + 1):
            pn = (page - 1) * 50
            filename = "" + str(page) + "页.html"
            fullurl = url + "&pn=" + str(pn)
            print(fullurl)
            html = loadPage(fullurl, filename)
            writePage(html, filename)
    
    
    if __name__ == "__main__":
        kw = input("请输入需要爬取的贴吧名:")
        beginPage = int(input("请输入起始页编号"))
        endPage = int(input("请输入结束页编号:"))
        url = "http://tieba.baidu.com/f?"
        key = parse.urlencode({"kw": kw})
        fullurl = url + key
        tiebaSpider(fullurl, beginPage, endPage)
    View Code

    其实很多网站都是这样的,同类网站下的html页面编号,分别对应网址后的网页序号,只要发现规律就可以批量爬取页面了。

  • 相关阅读:
    Flutter Web预览时白屏解决方法
    提高IIS并发数量设置
    学习如何看懂SQL Server执行计划(一)——数据查询篇
    Sql Server 死锁相关sql语句
    IIS共享文件站点配置
    Newtonsoft.Json保留小数Convert
    git克隆代码出现Authentication failed for “http://xxxxxx“ 解决方案
    Sql Server无用索引查询
    Sql Server索引基本知识篇
    SQL Server 锁机制 悲观锁 乐观锁 实测解析
  • 原文地址:https://www.cnblogs.com/amou/p/9131495.html
Copyright © 2020-2023  润新知