博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
运维学python之爬虫基础篇实战(六)爬取百度贴吧
阅读量:6154 次
发布时间:2019-06-21

本文共 5468 字,大约阅读时间需要 18 分钟。

相对来说,贴吧还是比较好爬一些的,所以就先拿贴吧为例,来做第一个实战。

1 爬前分析

如果要爬取一个网站的内容,我们要先做一般有以下几个步骤:

  • 对url进行分析,找到有规律的内容,定义相应的变量;
  • 开始爬取内容,对获取的内容进行查看;
  • 通过查看,设定正则规则,过滤无用内容;
  • 保存我们需要的内容到文件。

2 url分析

因为上大学时候就很迷恋盗墓笔记,一直关注着,所以这次就爬盗墓笔记吧的内容吧,。

2.1 url分段

盗墓笔记吧的一个帖子网址如下:

https:// # 使用的传输协议

tieba.baidu.com # 是百度的二级域名,指向百度贴吧的服务器。
/p/4366865181 # 服务器的路径
see_lz=1和pn=1分别表示只看楼主和页数
所以,url部分我们就分位两部分,基础部分和参数部分,结合到具体例子可以指定
基础部分:
参数部分:see_lz=1&pn=1

2.2 抓取页面

这里就用到了前面讲的urllib模块,下面直接看代码:

# -*- coding: utf-8 -*-# 爬取百度贴吧楼主发送的文字内容,存储在本地文件中# 导入模块from urllib import request# 定义查看楼主和页数seelz = '?see_lz=' + '1'pn = '&pn=' + '1'# 定义基础urlbase_url = 'https://tieba.baidu.com/p/4366865181'# 定义参数urlarg_url = seelz + pn# 完整urlurl = base_url + arg_url# 看一下打出来的网址有没有达到预期效果print(url)try:    # 添加请求头,我发现贴吧不加头也能获取,不过最好还是加上    head = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0'}    # 创建对象    req = request.Request(url, headers=head)    # 打开网址    response = request.urlopen(req)    # 打印结果    print(response.read().decode('utf-8'))except request.URLError as e:    if hasattr(e, 'code'):        print(e.code)    elif hasattr(e, 'reason'):        print(e.reason)

输出结果如下:

运维学python之爬虫基础篇实战(六)爬取百度贴吧
可以看出成功获取了网页的内容。

2.3 正则表达式提取信息

接着就是提取对我们有用的信息了,可以分步操作,大事化小,小事化了,我们先提取标题,可以看一下网页的源代码,找到标题(浏览器为火狐):

运维学python之爬虫基础篇实战(六)爬取百度贴吧
通过上图操作我们可以找到标题部分的代码:

【分析】关于“十年结局”的一些猜度

下面开始写pattern

pattern = re.compile('<h3 class="core_title_txt.?">(.?)</h3>')含义如下:
运维学python之爬虫基础篇实战(六)爬取百度贴吧
代码实现效果如下:

# -*- coding: utf-8 -*-# 爬取百度贴吧楼主发送的文字内容,存储在本地文件中# 导入模块import refrom urllib import request# 定义查看楼主和页数seelz = '?see_lz=' + '1'pn = '&pn=' + '1'# 定义基础urlbase_url = 'https://tieba.baidu.com/p/4366865181'# 定义参数urlarg_url = seelz + pn# 完整urlurl = base_url + arg_url# 看一下打出来的网址有没有达到预期效果print(url)try:    # 添加请求头,我发现贴吧不加头也能获取,不过最好还是加上    head = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0'}    # 创建对象    req = request.Request(url, headers=head)    # 打开网址    response = request.urlopen(req).read().decode('utf-8')    # 定义过滤规则    pattern = re.compile('

(.*?)

') # 查询匹配结果 result = re.search(pattern, response) # 判断是否存在结果,如果存在打印,如果不存在返回None if result: print(result.group(1).strip()) else: print(None)except request.URLError as e: if hasattr(e, 'code'): print(e.code) elif hasattr(e, 'reason'): print(e.reason)

执行结果如下:

运维学python之爬虫基础篇实战(六)爬取百度贴吧
好,基本满足我们的需求,那问题来了,如何获取本页所有的内容呢?我们继续,为了节省篇幅,代码只写修改的内容,其它部分和上面相同,如果参数不同,做替换即可

略    # 打开网址    response = request.urlopen(req).read().decode('utf-8')    # 定义过滤规则    pattern1 = re.compile('

(.*?)

', re.S) # 过滤楼主说过的内容 pattern2 = re.compile('

运维学python之爬虫基础篇实战(六)爬取百度贴吧

结果实现了我们要获取内容个的想法,but,从图中我们也发现了,有很多<a>、<img>、<br>等标签干扰,那就继续,去掉干扰

# -*- coding: utf-8 -*-# 爬取百度贴吧楼主发送的文字内容,存储在本地文件中# 导入模块import refrom urllib import request# 定义查看楼主和页数seelz = '?see_lz=' + '1'pn = '&pn=' + '1'# 定义基础urlbase_url = 'https://tieba.baidu.com/p/4366865181'# 定义参数urlarg_url = seelz + pn# 完整urlurl = base_url + arg_url# 看一下打出来的网址有没有达到预期效果print(url)try:    # 添加请求头,我发现贴吧不加头也能获取,不过最好还是加上    head = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0'}    # 创建对象    req = request.Request(url, headers=head)    # 打开网址    response = request.urlopen(req).read().decode('utf-8')    # 定义过滤规则    pattern1 = re.compile('

(.*?)

', re.S) pattern2 = re.compile('

获取结果如下:

运维学python之爬虫基础篇实战(六)爬取百度贴吧

是不是看着有些意思了,感觉可以接受了,但是还有一个问题,就是代码看起来太乱了,不方便扩展,如果爬取别的网页呢?多页怎么办,好吧,那我们就用类的方式来实现,完整代码如下:

# -*- coding: utf-8 -*-import refrom urllib import requestclass InitTool:    """    定义初始化类,目的是去除获取代码内容中的各种无用标签    """    # 去除img标签    removeimg = re.compile('
') # 去除br标签 replacebr = re.compile('
|
') # 去除a标签 removea = re.compile('
|') # 去除其它除了上述标签的标签 removeothertag = re.compile('<.*?>') # 定义类的方法,去除无用的标签 def replace(self, x): x = re.sub(self.removeimg, '', x) x = re.sub(self.removea, '', x) x = re.sub(self.removeothertag, '', x) x = re.sub(self.replacebr, '\n', x) # 删除x前后多余的空格 return x.strip()class BdTb: """ 定义类,获取网页标题,内容 """ def __init__(self, baseurl, seelz): """ 传入基础地址,是否只看楼主等信息 """ # 基础地址 self.baseurl = baseurl # 是否只看楼主 self.seelz = '?see_lz=' + str(seelz) # 调用去除标签工具,去除无用标签,注意InitTool后面的括号不要丢 self.inittool = InitTool() # 默认标题 # self.defaultTitle = '百度贴吧' def getpage(self, pn): """ 传入页码,获取该页帖子代码,pn为页码 """ try: # 构建url url = self.baseurl + self.seelz + '&pn=' + str(pn) # 请求头信息 head = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0'} # 发送请求 req = request.Request(url, headers=head) # 打开网址获取内容 response = request.urlopen(req) # 返回utf-8格式文本 return response.read().decode('utf-8') except request.URLError as e: # 如果有reason,打印报错原因 if hasattr(e, 'reason'): print('连接失败,错误原因:', e.reason) return None def gettitle(self, page): """ 获取帖子标题 """ # 定义获取标题正则,re.S代表.可以匹配任何内容,包括'\n'换行 pattern = re.compile('

(.*?)

', re.S) result = re.search(pattern, page) if result: # 如果存在返回标题 return result.group(1).strip() else: return None def getpagenum(self, page): """ 获取帖子的总页数 """ # 定义获取总共页数的正则 pattern = re.compile('

结果如下:

运维学python之爬虫基础篇实战(六)爬取百度贴吧

本文内容参考:

转载于:https://blog.51cto.com/linuxliu/2052232

你可能感兴趣的文章
数据库之MySQL
查看>>
2019/1/15 批量删除数据库相关数据
查看>>
数据类型的一些方法
查看>>
AOP
查看>>
NGUI Label Color Code
查看>>
Webpack 2 中一些常见的优化措施
查看>>
移动端响应式
查看>>
js中var、let、const的区别
查看>>
简洁优雅地实现夜间模式
查看>>
react学习总结
查看>>
在soapui上踩过的坑
查看>>
MySQL的字符集和字符编码笔记
查看>>
ntpd同步时间
查看>>
must implement java.io.Serializable hessian
查看>>
Microsoft Licenses Flash Lite for Windows Mobile Users
查看>>
HDOJ 2020 绝对值排序
查看>>
HDOJ/HDU 2560 Buildings(嗯~水题)
查看>>
Maven编译时跳过Test
查看>>
Spring Boot 整合Spring Security 和Swagger2 遇到的问题小结
查看>>
[20170628]12C ORA-54032.txt
查看>>