程序功能说明:爬取百度贴吧帖子中的图片,用户输入贴吧名称和要爬取的起始和终止页数即可进行爬取。

思路分析:

一、指定贴吧url的获取

例如我们进入秦时明月吧,提取并分析其有效url如下

http://tieba.baidu.com/f?kw=%E7%A7%A6%E6%97%B6%E6%98%8E%E6%9C%88

?后面为查询字符串,“%E7%A7%A6%E6%97%B6%E6%98%8E%E6%9C%88“是贴吧名称“秦时明月”的url编码。

这样我们就可以通过构造请求进入每一个贴吧了,代码实现如下:

import urllib
# 贴吧url前半部分
url = "http://tieba.baidu.com/f?"
value = raw_input("请输入要爬取的贴吧名称:")
# 将查询字符串转换为url编码形式
key = urllib.urlencode({"kw":value})
# 组合完整的贴吧url
url = url + key
# 查看完整url
print url

运行程序,这里输入“天行九歌”作为演示,可以得到天行九歌吧的完整链接如下:

http://tieba.baidu.com/f?kw=%CC%EC%D0%D0%BE%C5%B8%E8

这样就可以获取任意贴吧的链接了。

获取贴吧指定页数的链接:

我们进入天行九歌吧,取出该贴吧第2页到底4页的url,如下:

http://tieba.baidu.com/f?kw=%E7%A7%A6%E6%97%B6%E6%98%8E%E6%9C%88&pn=50

http://tieba.baidu.com/f?kw=%E7%A7%A6%E6%97%B6%E6%98%8E%E6%9C%88&pn=100

http://tieba.baidu.com/f?kw=%E7%A7%A6%E6%97%B6%E6%98%8E%E6%9C%88&pn=150

我们发现,每一页的url变化的是pn的值,依次增加50,结合上面贴吧完整的url,要想获得每一页的链接可以如下实现:

import urllib
url = "http://tieba.baidu.com/f?"
value = raw_input("请输入要爬取的贴吧名称:")
key = urllib.urlencode({"kw":value})
# 贴吧完整url
url = url + key
begin_page = int(raw_input("请输入起始页:"))
end_page = int(raw_input("请输入终止页:"))
for page in range(begin_page, end_page+1):
pn = (page-1)*50
  # 组合出贴吧每一页的url
full_url = url + "&pn=" + str(pn)
print full_url

运行程序,输入贴吧名称:“天行九歌”,再输入起始页1,终止页5,可得到如下结果:

这样我们就可以拿到贴吧每一页的链接了。

获取贴吧每一页中帖子的链接:

选择一个帖子,首先查看该帖子的元素得到:

<a href="/p/5344262338" title="端木蓉为何一直不苏醒" target="_blank" class="j_th_tit ">端木蓉为何一直不苏醒</a>

然后进入这个帖子取得它的完整链接:

http://tieba.baidu.com/p/5344262338

分析可得:完整链接可由两部分组成,http://tieba.baidu.com和/p/5344262338,后面的部分可以从页面源码中提取,使用xpath规则提取如下:

xpath提取规则://a[@class="j_th_tit"]/@href(先在浏览器中使用插件匹配,规则很多,找到合适的就行)

下面选择第二页帖子链接做如下演示

# -*- coding: utf-8 -*-
import urllib2
from lxml import etree
# 贴吧第二页url
url = "http://tieba.baidu.com/f?kw=%E5%A4%A9%E8%A1%8C%E4%B9%9D%E6%AD%8C&pn=50"
request = urllib2.Request(url)
html = urllib2.urlopen(request).read()
content = etree.HTML(html)
# 匹配这一页中所以帖子链接的后半部分
link_list = content.xpath('//div[@class="t_con cleafix"]/div/div/div/a/@href')
for link in link_list:
  # 组合为完整帖子链接
fulllink = "http://tieba.baidu.com" + link
print fulllink

运行程序,则可取该页中帖子的链接(展示部分)

这样就拿到了每个帖子的链接了。

获取每一个帖子中图片的链接:

进入一个帖子,找到发布的图片查看元素:

<img class="BDE_Image" src="https://imgsa.baidu.com/forum/w%3D580/sign=c1cc6b66b819ebc4c0787691b227cf79/3577812397dda14415c938b1b9b7d0a20df48615.jpg" pic_ext="jpeg" size="39874" height="600" width="450">

使用xpath规则提取图片链接:

xpath提取规则://img[@class="BDE_Image"]/@src

取上面第一个帖子做演示:

# -*- coding: utf-8 -*-
import urllib2
from lxml import etree
# 第一个帖子的url
url = "http://tieba.baidu.com/p/5341810557"
headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
request = urllib2.Request(url, headers = headers)
html = urllib2.urlopen(request).read()
content = etree.HTML(html)
# 匹配出帖子中的图片链接
link_list = content.xpath('//img[@class="BDE_Image"]/@src')
for link in link_list:
print link

运行程序,取得帖子中图片链接(展示部分)

到现在为止,我们已经可以进入任意一个贴吧,获取每个贴吧指定页数的响应,并且可以拿到每个帖子中的图片链接,接下来要做的就是以图片链接发送请求获取响应文件保存下来即可。

保存图片到本地:

import urllib2
# 取得的图片链接
url = "http://imgsa.baidu.com/forum/w%3D580/sign=b42c88339945d688a302b2ac94c37dab/541d5d510fb30f243576ad03c395d143ac4b0352.jpg"
headers = {"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36"}
request = urllib2.Request(url, headers = headers)
image = urllib2.urlopen(request).read()
# 将图片链接后10位作为图片文件名称
filename = url[-10:]
# 保存图片到本地
with open(filename, "wb") as f:
f.write(image)

运行程序,图片就会保存到当前的工作目录中。

完整程序

整个过程就是这样了,根据上面的分析,写出的完整程序如下:

#!/usr/bin/env python
# -*- coding:utf-8 -*- import urllib
import urllib2
from lxml import etree def loadPage(url):
"""
作用:根据url发送请求,获取服务器响应文件
url: 需要爬取的url地址
"""
headers = {"User-Agent" : "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}
request = urllib2.Request(url, headers=headers)
html = urllib2.urlopen(request).read()
content = etree.HTML(html)
# 匹配每个帖子url的后半部分
link_list = content.xpath('//a[@class="j_th_tit"]/@href')
for link in link_list:
# 组合为每个帖子的完整链接
fulllink = "http://tieba.baidu.com" + link
loadImage(fulllink) def loadImage(link):
"""
作用:取出每个帖子里的每个图片连接
link:每个帖子的链接
"""
headers = {"User-Agent" : "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}
request = urllib2.Request(link, headers = headers)
html = urllib2.urlopen(request).read()
content = etree.HTML(html)
# 匹配帖子里发送的图片链接
link_list = content.xpath('//img[@class="BDE_Image"]/@src')
# 取出每个图片的连接
for link in link_list:
writeImage(link) def writeImage(link):
"""
作用:将图片保存到本地
link:图片连接
"""
headers = {"User-Agent" : "Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;"}
request = urllib2.Request(link, headers = headers)
image = urllib2.urlopen(request).read()
filename = link[-10:]
with open(filename, "wb") as f:
f.write(image)
print "已经成功下载 "+ filename def tiebaSpider(url, beginPage, endPage):
"""
作用:负责组合处理贴吧每个页面的url
url : 贴吧url的前部分
beginPage : 起始页
endPage : 结束页
"""
for page in range(beginPage, endPage + 1):
pn = (page - 1) * 50
fullurl = url + "&pn=" + str(pn)
loadPage(fullurl)
print "谢谢使用" if __name__ == "__main__":
kw = raw_input("请输入需要爬取的贴吧名:")
beginPage = int(raw_input("请输入起始页:"))
endPage = int(raw_input("请输入结束页:"))
url = "http://tieba.baidu.com/f?"
key = urllib.urlencode({"kw": kw})
fullurl = url + key
tiebaSpider(fullurl, beginPage, endPage)

运行程序,输入你要爬取的贴吧名称和要爬取的页数,图片就可以下载到你的工作目录下了。

Python爬虫实例(一)爬取百度贴吧帖子中的图片的更多相关文章

  1. Python爬虫实战之爬取百度贴吧帖子

    大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 本篇目标 对百度贴吧的任意帖子进行抓取 指定是否只抓取楼主发帖 ...

  2. 芝麻HTTP:Python爬虫实战之爬取百度贴吧帖子

    本篇目标 1.对百度贴吧的任意帖子进行抓取 2.指定是否只抓取楼主发帖内容 3.将抓取到的内容分析并保存到文件 1.URL格式的确定 首先,我们先观察一下百度贴吧的任意一个帖子. 比如:http:// ...

  3. Python爬虫实例:爬取B站《工作细胞》短评——异步加载信息的爬取

    很多网页的信息都是通过异步加载的,本文就举例讨论下此类网页的抓取. <工作细胞>最近比较火,bilibili 上目前的短评已经有17000多条. 先看分析下页面 右边 li 标签中的就是短 ...

  4. Python爬虫实例:爬取猫眼电影——破解字体反爬

    字体反爬 字体反爬也就是自定义字体反爬,通过调用自定义的字体文件来渲染网页中的文字,而网页中的文字不再是文字,而是相应的字体编码,通过复制或者简单的采集是无法采集到编码后的文字内容的. 现在貌似不少网 ...

  5. Python爬虫实例:爬取豆瓣Top250

    入门第一个爬虫一般都是爬这个,实在是太简单.用了 requests 和 bs4 库. 1.检查网页元素,提取所需要的信息并保存.这个用 bs4 就可以,前面的文章中已经有详细的用法阐述. 2.找到下一 ...

  6. Python 爬虫练习: 爬取百度贴吧中的图片

    背景:最近开始看一些Python爬虫相关的知识,就在网上找了一些简单已与练习的一些爬虫脚本 实现功能:1,读取用户想要爬取的贴吧 2,读取用户先要爬取某个贴吧的页数范围 3,爬取每个贴吧中用户输入的页 ...

  7. 【python爬虫】 之 爬取百度首页

    刚开始学习爬虫,照着教程手打了一遍,还是蛮有成就感的.使用版本:python2.7 注意:python2的默认编码是ASCII编码而python3默认编码是utf-8 import urllib2 u ...

  8. Python爬虫实战二之爬取百度贴吧帖子

    大家好,上次我们实验了爬取了糗事百科的段子,那么这次我们来尝试一下爬取百度贴吧的帖子.与上一篇不同的是,这次我们需要用到文件的相关操作. 前言 亲爱的们,教程比较旧了,百度贴吧页面可能改版,可能代码不 ...

  9. Python爬虫教程-17-ajax爬取实例(豆瓣电影)

    Python爬虫教程-17-ajax爬取实例(豆瓣电影) ajax: 简单的说,就是一段js代码,通过这段代码,可以让页面发送异步的请求,或者向服务器发送一个东西,即和服务器进行交互 对于ajax: ...

随机推荐

  1. 用wget做站点镜像

    用wget做站点镜像 -- :: 分类: LINUX # wget -r -p -np -k http://xxx.edu.cn -r 表示递归下载,会下载所有的链接,不过要注意的是,不要单独使用这个 ...

  2. 解决Collection <__NSArrayM: 0xb550c30> was mutated while being enumerated.-

    bug: 今天做项目的时候遇到了这样一个崩溃信息: 解决Collection <__NSArrayM: 0xb550c30> was mutated while being enumera ...

  3. 结构体内重载小于号< 及构造函数

    struct Node { int d, e; bool operator < (const Node x) const { return x.d < d; } Node(int d, i ...

  4. strcmp在CTF中的案例

    当strcmp比较出错的时候就会为null.null即为0故输出flag. strcmp(arr,str); ?test[]=1 <?php define('FLAG', 'pwnhub{THI ...

  5. SpringMVC请求后台地址URL没有.*的几种实现方式

    今天做项目,由于项目是通过扫二维码进入,二维码存放的地址不希望有 .do,而是http:xxxx:8080/xxx/yyy/zzz的格式(zzz为参数),但是项目其它请求url后面都必须要有.do,想 ...

  6. Java调用doNet webService方法

    doNet的webService 浏览器访问测试地址:http://192.168.4.17/JLWWS/sendCommand.asmx,出现 点击getDeviceValue方法,出现 上图的xm ...

  7. ZooKeeper是以Fast Paxos算法为基础的

    ZooKeeper是以Fast Paxos算法为基础的,Paxos 算法存在活锁的问题,即当有多个proposer交错提交时,有可能互相排斥导致没有一个proposer能提交成功,而Fast Paxo ...

  8. getRequestDispatcher 和sendRedirect区别及路径问题

    getRequestDispatcher 和sendRedirect区别   getRequestDispatcher是服务器内部跳转,地址栏信息不变,只能跳转到web应用内的网页. sendRedi ...

  9. jQuery实现瀑布流布局详解(PC和移动端)

    首先我们将如下样式的若干个单元写进body中,并将“box”向左浮动: <div class="box">  <img class="img" ...

  10. ChemDraw Pro绘制无环链结构的两种方法

    ChemDraw Pro 14是一款专门针对化学图形绘制而开发制作的编辑软件,是目前工科类常用的绘制化学结构工具,用于快速绘制常用的环结构组成.以下教程讲解ChemDraw Pro绘制无环链结构的两种 ...