爬取贴吧页面

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页面编号,分别对应网址后的网页序号,只要发现规律就可以批量爬取页面了。

猜你喜欢

转载自www.cnblogs.com/amou/p/9131495.html