利用正则爬取百度贴吧;;反爬虫措施

例子
爬取nba百度贴吧:

# coding: utf-8
# 引入请求包
import requests
# 引入正则表达式包
import re

# 1.准备url
url = 'https://tieba.baidu.com/p/5082744218'
# 2.获取网页源代码,发起请求接收响应
response = requests.get(url)
html = response.content

# 3.获取网页标题
# 3.1 准备网页标题的正则表达式
title_pat = re.compile(r'<title>(.*?)</title>')
# 3.2 使用search()函数搜索符合正则的字符串
rs = re.search(title_pat, html)
# 3.3 根据当前帖子的标题,拼接文件名称
file_name = rs.group(1)+'.txt'
file_handle = open(file_name.decode('utf-8'),'w')

# 4.获取总页数
# 4.1 准备总页数的正则表达式
pages_pat = re.compile(r'共<span class="red">(.*?)</span>')
# 4.2 使用search()函数搜索符合正则的字符串
rs = re.search(pages_pat, html)
# 4.3 取出总页数字符,转换为整数类型
total_page = int(rs.group(1))
print '该帖子共有%s页!'%total_page
# for循环遍历总页码次
for x in range(1, total_page+1):
    print '正在爬取第%s页,请稍后.....'%x
    # 5.根据x的值,拼接完整的url地址
    url = 'https://tieba.baidu.com/p/5082744218?pn=%s'%x
    # 6.发起请求,获取该页的html源代码
    response = requests.get(url)
    html = response.content
    # 7.准备提取数据的正则,使用re.S 可以匹配到任何字符
    pattern = re.compile(r'<li class="d_name".*?<a data-.*?>(.*?)</a>.*?<div class="d_badge_title.*?>(.*?)</div>.*?d_badge_lv">(.*?)</div>.*?<cc>(.*?)</cc>.*?<span class="tail-info.*?<a.*?>(.*?)</a>.*?<spa.*?>(.*?)</spa.*?info">(.*?)</span>', re.S)
    # 8.使用findall()查找所有符合正则的字符
    rs = re.findall(pattern, html)

    # for 循环所有数据
    for detail in rs:
        # print detail
        # 1.取出用户名
        name =  detail[0]
        # 1.1 对用户名信息进行处理
        replace_img = re.compile(r'<img.*?>')
        # 1.2 替换为-
        name = re.sub(replace_img, '-', name)
        # 2.取出头衔
        rank = detail[1]
        # 3.取出等级
        level = detail[2]
        # 4.楼层内容
        content = detail[3]
        # 4.1 替换<br>标签为\n
        content = content.replace('<br>', '\n')
        # 4.2 剔除所有的标签
        strip_ele = re.compile(r'<.*?>')
        content = re.sub(strip_ele, '', content)
        # 4.3 去除空格
        content = content.strip()
        # print content
        # 5.取出客户端
        from_device = '来自' + detail[4]
        # 如果没有客户端,就设置为来自电脑端
        if 'img' in detail[4]:
            from_device = '来自PC电脑端'
        # 6.取出楼层
        floor_num = detail[5]
        if 'a' in floor_num:
            floor_num = '未知'
        # 7.取出时间
        datetime = detail[6]
        if 'a' in detail[6]:
            datetime = '未知'
        file_handle.write('***************%s******************\n'%floor_num)
        file_handle.write('用户名:%s   头衔:%s   等级%s\n'%(name, rank, level))
        file_handle.write(content)
        file_handle.write('\n')
        file_handle.write('%s 日期:%s\n\n'%(from_device, datetime))

file_handle.close()

例子
先爬取某个具体帖子中的全部内容,形成一个模块
再写一个爬取一个贴吧全部帖子的链接,调用爬取具体内容的链接

爬取具体帖子内容

# coding: utf-8
# 引入请求包
import requests
# 引入正则表达式包
import re
# 获取一个帖子的全部内容
# 根据帖子编号和页码获取html源代码
def get_html(numbers, page):
    # 1.根据帖子编号和页码拼接完整的url地址
    url = 'https://tieba.baidu.com/p/%s?pn=%s'%(numbers, page)
    # 2.根据url地址请求该页的html源代码
    response = requests.get(url)
    html = response.content
    return html
# 获取存储文件名称,给一个html源代码,返回一个存储的文件名称
def get_filename(html):
    # 1 准备网页标题的正则表达式
    title_pat = re.compile(r'<title>(.*?)</title>')
    # 2 使用search()函数搜索符合正则的字符串
    rs = re.search(title_pat, html)
    # 输出正在爬取的帖子名称
    print '正在爬取:%s......'%rs.group(1)
    # 3 根据当前帖子的标题,拼接文件名称
    file_name = rs.group(1) + '.txt'
    return file_name
# 获取帖子的总页数
def get_total_page(html):
    # 4.1 准备总页数的正则表达式
    pages_pat = re.compile(r'共<span class="red">(.*?)</span>')
    # 4.2 使用search()函数搜索符合正则的字符串
    rs = re.search(pages_pat, html)
    # 4.3 取出总页数字符,转换为整数类型
    total_page = int(rs.group(1))
    # 输出正在爬取的帖子有多少页
    print '该贴共%s页,正在准备爬取,请稍后......'%total_page
    return total_page

# 获取帖子每一页的数据
def get_result_data(total_page, numbers):
    # 声明一个大列表,用来存放所有页的数据
    result_list = []
    # for循环遍历总页码次
    for x in range(1, total_page + 1):
        print '正在爬取第%s页,请稍后.....' % x
        # 传入一个numbers和页码,获取网页源代码
        html = get_html(numbers, x)
        # 7.准备提取数据的正则,使用re.S 可以匹配到任何字符
        pattern = re.compile(
            r'<li class="d_name".*?<a data-.*?>(.*?)</a>.*?<div class="d_badge_title.*?>(.*?)</div>.*?d_badge_lv">(.*?)</div>.*?<cc>(.*?)</cc>.*?<span class="tail-info.*?<a.*?>(.*?)</a>.*?<spa.*?>(.*?)</spa.*?info">(.*?)</span>',
            re.S)
        # 8.使用findall()查找所有符合正则的字符
        rs = re.findall(pattern, html)
        # 把爬取的这一页数据放入大列表中
        result_list.append(rs)
    # 返回大列表
    return result_list
# 根据数据列表和文件名称,存储数据
def save_data(filename, result_list):
    # 1.打开文件
    file_handle = open(filename.decode('utf-8'),'w')
    # 2.for循环遍历每一页的数据
    for rs in result_list:
        # for 循环遍历每一条数据
        for detail in rs:
            # print detail
            # 1.取出用户名
            name = detail[0]
            # 1.1 对用户名信息进行处理
            replace_img = re.compile(r'<img.*?>')
            # 1.2 替换为-
            name = re.sub(replace_img, '-', name)
            # 2.取出头衔
            rank = detail[1]
            # 3.取出等级
            level = detail[2]
            # 4.楼层内容
            content = detail[3]
            # 4.1 替换<br>标签为\n
            content = content.replace('<br>', '\n')
            # 4.2 剔除所有的标签
            strip_ele = re.compile(r'<.*?>')
            content = re.sub(strip_ele, '', content)
            # 4.3 去除空格
            content = content.strip()
            # print content
            # 5.取出客户端
            from_device = '来自' + detail[4]
            # 如果没有客户端,就设置为来自电脑端
            if 'img' in detail[4]:
                from_device = '来自PC电脑端'
            # 6.取出楼层
            floor_num = detail[5]
            if 'a' in floor_num:
                floor_num = '未知'
            # 7.取出时间
            datetime = detail[6]
            if 'a' in detail[6]:
                datetime = '未知'
            file_handle.write('***************%s******************\n' % floor_num)
            file_handle.write('用户名:%s   头衔:%s   等级%s\n' % (name, rank, level))
            file_handle.write(content)
            file_handle.write('\n')
            file_handle.write('%s 日期:%s\n\n' % (from_device, datetime))

    # 3.关闭文件
    file_handle.close()
    print '数据爬取完毕,已存入*[%s]*,请稍后自行查看!'%filename


# 主函数,启动爬虫程序,进行数据的抓取和存储工作
# url 参数:要爬取的帖子的地址
def start(numbers):
    # 1.根据帖子编号,获取html源代码
    html = get_html(numbers, 1)
    # 2.从第一页的html源代码中提取帖子的名称并且拼接一个完整的文件名称
    filename = get_filename(html)
    # 3.从第一页的html源代码中提取帖子的总页数,返回一个数字总页数
    total_page = get_total_page(html)
    # 4.for循环获取网页中的数据,需要传入总页数和帖子编号
    result_list = get_result_data(total_page, numbers)
    # 5.写入数据,传入文件名称 ,传入爬取的所有页数据
    save_data(filename, result_list)


start(5082744218)

爬取贴吧的全部链接

# coding: utf-8
# 引入请求包
import requests
# 引入正则表达式包
import re
# 获取一个帖子的全部内容
# 根据帖子编号和页码获取html源代码
def get_html(numbers, page):
    # 1.根据帖子编号和页码拼接完整的url地址
    url = 'https://tieba.baidu.com/p/%s?pn=%s'%(numbers, page)
    # 2.根据url地址请求该页的html源代码
    response = requests.get(url)
    html = response.content
    return html
# 获取存储文件名称,给一个html源代码,返回一个存储的文件名称
def get_filename(html):
    # 1 准备网页标题的正则表达式
    title_pat = re.compile(r'<title>(.*?)</title>')
    # 2 使用search()函数搜索符合正则的字符串
    rs = re.search(title_pat, html)
    # 输出正在爬取的帖子名称
    print '正在爬取:%s......'%rs.group(1)
    # 3 根据当前帖子的标题,拼接文件名称
    file_name = rs.group(1) + '.txt'
    return file_name
# 获取帖子的总页数
def get_total_page(html):
    # 4.1 准备总页数的正则表达式
    pages_pat = re.compile(r'共<span class="red">(.*?)</span>')
    # 4.2 使用search()函数搜索符合正则的字符串
    rs = re.search(pages_pat, html)
    # 4.3 取出总页数字符,转换为整数类型
    total_page = int(rs.group(1))
    # 输出正在爬取的帖子有多少页
    print '该贴共%s页,正在准备爬取,请稍后......'%total_page
    return total_page

# 获取帖子每一页的数据
def get_result_data(total_page, numbers):
    # 声明一个大列表,用来存放所有页的数据
    result_list = []
    # for循环遍历总页码次
    for x in range(1, total_page + 1):
        print '正在爬取第%s页,请稍后.....' % x
        # 传入一个numbers和页码,获取网页源代码
        html = get_html(numbers, x)
        # 7.准备提取数据的正则,使用re.S 可以匹配到任何字符
        pattern = re.compile(
            r'<li class="d_name".*?<a data-.*?>(.*?)</a>.*?<div class="d_badge_title.*?>(.*?)</div>.*?d_badge_lv">(.*?)</div>.*?<cc>(.*?)</cc>.*?<span class="tail-info.*?<a.*?>(.*?)</a>.*?<spa.*?>(.*?)</spa.*?info">(.*?)</span>',
            re.S)
        # 8.使用findall()查找所有符合正则的字符
        rs = re.findall(pattern, html)
        # 把爬取的这一页数据放入大列表中
        result_list.append(rs)
    # 返回大列表
    return result_list
# 根据数据列表和文件名称,存储数据
def save_data(filename, result_list):
    # 1.打开文件
    file_handle = open(filename.decode('utf-8'),'w')
    # 2.for循环遍历每一页的数据
    for rs in result_list:
        # for 循环遍历每一条数据
        for detail in rs:
            # print detail
            # 1.取出用户名
            name = detail[0]
            # 1.1 对用户名信息进行处理
            replace_img = re.compile(r'<img.*?>')
            # 1.2 替换为-
            name = re.sub(replace_img, '-', name)
            # 2.取出头衔
            rank = detail[1]
            # 3.取出等级
            level = detail[2]
            # 4.楼层内容
            content = detail[3]
            # 4.1 替换<br>标签为\n
            content = content.replace('<br>', '\n')
            # 4.2 剔除所有的标签
            strip_ele = re.compile(r'<.*?>')
            content = re.sub(strip_ele, '', content)
            # 4.3 去除空格
            content = content.strip()
            # print content
            # 5.取出客户端
            from_device = '来自' + detail[4]
            # 如果没有客户端,就设置为来自电脑端
            if 'img' in detail[4]:
                from_device = '来自PC电脑端'
            # 6.取出楼层
            floor_num = detail[5]
            if 'a' in floor_num:
                floor_num = '未知'
            # 7.取出时间
            datetime = detail[6]
            if 'a' in detail[6]:
                datetime = '未知'
            file_handle.write('***************%s******************\n' % floor_num)
            file_handle.write('用户名:%s   头衔:%s   等级%s\n' % (name, rank, level))
            file_handle.write(content)
            file_handle.write('\n')
            file_handle.write('%s 日期:%s\n\n' % (from_device, datetime))

    # 3.关闭文件
    file_handle.close()
    print '数据爬取完毕,已存入*[%s]*,请稍后自行查看!'%filename


# 主函数,启动爬虫程序,进行数据的抓取和存储工作
# url 参数:要爬取的帖子的地址
def start(numbers):
    # 1.根据帖子编号,获取html源代码
    html = get_html(numbers, 1)
    # 2.从第一页的html源代码中提取帖子的名称并且拼接一个完整的文件名称
    filename = get_filename(html)
    # 3.从第一页的html源代码中提取帖子的总页数,返回一个数字总页数
    total_page = get_total_page(html)
    # 4.for循环获取网页中的数据,需要传入总页数和帖子编号
    result_list = get_result_data(total_page, numbers)
    # 5.写入数据,传入文件名称 ,传入爬取的所有页数据
    save_data(filename, result_list)


start(5082744218)

反爬虫措施


# coding: utf-8

import requests
# 反爬虫措施:
# 1.判断用户代理 User-Agent  如果发现是以python开头,直接拒绝提供服务
# 解决方案:模拟浏览器的User-Agent

# 2.ip  统一个ip或者网段 频繁访问服务器 ,例如1分钟访问1W+次,正常用户肯定访问不了这么多次,会认为这就是个爬虫程序或爬虫机器人,直接封杀ip
# 解决方案:使用代理ip

# 3.限制访问频率  服务器会判断某个ip访问的频率  设置访问平率

# 4.验证码 ,使用云打码平台

headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0'}

response = requests.get('http://sou.zhaopin.com/jobs/searchresult.ashx?jl=%E5%8C%97%E4%BA%AC%2B%E4%B8%8A%E6%B5%B7%2B%E5%B9%BF%E5%B7%9E%2B%E6%B7%B1%E5%9C%B3%2B%E6%9D%AD%E5%B7%9E&kw=python&sm=0&p=2',headers=headers)

print response.content

发布了19 篇原创文章 · 获赞 6 · 访问量 6191

猜你喜欢

转载自blog.csdn.net/weixin_41580211/article/details/79089430