爬虫_获取单页百度贴吧图片



2.7和3的区别是2.7没有request,直接导入urllib即可,作用一样



Step 1

爬取这个网址中的图片:http://tieba.baidu.com/p/2166231880,Python2.7:

# 爬取贴吧图片,网址:http://tieba.baidu.com/p/2166231880
#-*- coding:utf-8 -*- 
import urllib
import re
import os
 
def fetch_pictures(url):
    html_content = urllib.urlopen(url).read()
    r = re.compile('<img pic_type="0" class="BDE_Image" src="(.*?)"')
    picture_url_list = r.findall(html_content.decode('utf-8'))    
    os.mkdir('e:/pictures')
    os.chdir('e:/pictures')   
    for i in range(len(picture_url_list)):
        picture_name = str(i) + '.jpg'
        try:
            urllib.urlretrieve(picture_url_list[i], picture_name)
            print("Success: " + picture_url_list[i])
        except:
            print("Fail: " + picture_url_list[i])
if __name__ == '__main__':
    fetch_pictures("http://tieba.baidu.com/p/2166231880")

运行之后,会生成 e:/pictures 文件夹,自动下载图片并存放进去,色情图片就不截图了。


为了测试该程序,看了另一个Python爬虫的代码,网址替换一下,即爬取这个网址中的图片:http://tieba.baidu.com/p/2460150866 ,只需要将上述代码稍作修改(网址换一下,文件夹改一下),如下

#-*- coding:utf-8 -*- 
import urllib
import re
import os
 
def fetch_pictures(url):
    # 读取url指向的网页
    html_content = urllib.urlopen(url).read()
    # 正则匹配compile函数,compile返回的是一个匹配对象,单独使用没有任何用处
    r = re.compile('<img pic_type="0" class="BDE_Image" src="(.*?)"')
    # findall()根据r提供的返回对象格式,查询读取的html中所有相同格式数,返回一个列表
    picture_url_list = r.findall(html_content.decode('utf-8'))
    # print(picture_url_list) 这里打印出所有获取到的url,可以看到格式为:u'https://imgsa.baidu.com/forum/w%3D580/sign=294db374d462853592e0d229a0ee76f2/e732c895d143ad4b630e8f4683025aafa40f0611.jpg'
    
    # mkdir()指定path创建文件,chdir()改变当前工作目录到指定的路径
    os.mkdir('e:/pictures')
    os.chdir('e:/pictures')   
    # 有几个图片url就重复几次,并且给图片命名为012345.jpg
    for i in range(len(picture_url_list)):
        picture_name = str(i) + '.jpg'
        try:
            # urlretrieve(url,文件名)将远程数据下载到本地
            urllib.urlretrieve(picture_url_list[i], picture_name)
            print("Success: " + picture_url_list[i])
        except:
            print("Fail: " + picture_url_list[i])

if __name__ == '__main__':
    fetch_pictures("http://tieba.baidu.com/p/2460150866")

成功,截图如下: 

happysneaker.com


分析一下程序:

1. 为什么正则匹配compile那样写,爬取前去网页看下图片的检查元素,发现:<img pic_type="0" class="BDE_Image" src="https://imgsa.baidu.com/forum/w%3D580/sign=941c6a9596dda144da096cba82b6d009/e889d43f8794a4c2e5d529ad0ff41bd5ac6e3947.jpg" pic_ext="jpeg" height="350" width="560">  ;

2. x=complie() 设定正则规则,配合 x.findall( 被查找的范围 ) 找到后以列表返回;

3.  urlretrieve(url,设置文件名)将远程数据下载到本地:  urllib.urlretrieve(picture_url_list[i], picture_name)





Step 2


那下面来爬取一组明星的图片,比如刘诗诗,网址:http://tieba.baidu.com/p/2854146750 ,如果仍然直接把代码中的网址和文件夹名改一下,会发现并没有下载成功。所以,编程还是得老老实实看代码啊,光想着直接换个网址实在太偷懒。代码在抓取网页之后,利用正则表达式找到了图片的网址(URL),即关键在代码的这一行

r = re.compile('<img pic_type="0" class="BDE_Image" src="(.*?)"')


上面那两个例子之所以会成功,是因为网页源代码中(可以用谷歌浏览器查看)图片的网址确实是

<img pic_type="0" class="BDE_Image" src="

这个形式的,所以匹配到了。


而刘诗诗照片的网址呢,查看一下,是这样的: 

也就是里面img标签里的代码形式是不一样的,不是

<img pic_type="0" class="BDE_Image" src="(.*?)"

而是

<img class="BDE_Image" src="(.*?)" pic_ext="jpeg"  pic_type="0"

所以要把正则表达式的内容修改一下,整体代码如下:

#-*- coding:utf-8 -*- 
# 爬取贴吧刘诗诗的图片,网址:http://tieba.baidu.com/p/2854146750
 
import urllib
import re
import os
 
def fetch_pictures(url):
    html_content = urllib.urlopen(url).read()
    r = re.compile('<img class="BDE_Image" src="(.*?)" pic_ext="jpeg"  pic_type="0"')
    picture_url_list = r.findall(html_content.decode('utf-8'))
 
    os.mkdir('e:/liushishi')
    os.chdir('e:/liushishi')
    for i in range(len(picture_url_list)):
        picture_name = str(i) + '.jpg'
        try:
            urllib.urlretrieve(picture_url_list[i], picture_name)
            print("Success to download " + picture_url_list[i])
        except:
            print("Fail to download " + picture_url_list[i])
         
if __name__ == '__main__':
    fetch_pictures("http://tieba.baidu.com/p/2854146750")


爬取成功:

happysneaker.com

所以下载图片的关键在于正则表达式的匹配,要去看看图片的 img标签具体是怎么写的。




Step 3


以下是个简单的小案(fu)例(li),网址:http://tieba.baidu.com/p/3884688092 :

#-*- coding:utf-8 -*-
# 爬取贴吧图片,网址:http://tieba.baidu.com/p/3884688092
 
import urllib
import re
import os
 
def fetch_pictures(url):
    html_content = urllib.urlopen(url).read()
    r = re.compile('<img class="BDE_Image" pic_type="\d" width="\d\d\d" height="\d\d\d" src="(.*?)"')
    picture_url_list = r.findall(html_content.decode('utf-8'))
 
    os.mkdir('e:/test')
    os.chdir('e:/test')
    for i in range(len(picture_url_list)):
        picture_name = str(i) + '.jpg'
        try:
            urllib.urlretrieve(picture_url_list[i], picture_name)
            print("Success to download " + picture_url_list[i])
    	except:
            print("Fail to download " + picture_url_list[i])
     
if __name__ == '__main__':
    fetch_pictures("http://tieba.baidu.com/p/3884688092")


关键仍在于正则表达式那一行:

r = re.compile('<img class="BDE_Image" pic_type="\d" width="\d\d\d" height="\d\d\d" src="(.*?)"')



以上只是针对一页的图片进行爬取。


Web安全技术分享
请先登录后发表评论
  • 最新评论
  • 总共0条评论