python爬虫实战贴吧美女图片

这几日利用闲暇时间自学了python爬虫,来爬取各个有营养的网站。。。。。看着我手上日益厚拙的老茧。。。怎么能不分享出来给大家补充补充营养呢

-------------手动分割线-------------------
介绍下这个小项目,做的是爬取百度贴吧某吧所有贴子中的图片。
为了让大家更好理解这些代码,我们先简要分析一下三个问题,便于有个好思路写代码。
1.我们的目的是什么?
为了获取某吧中所有贴子中的图片。这次实战展示的是美女吧和头像吧。
2.我们的要求是什么?
每个贴中的图片分文件夹存放。
3.达到目的的结果是什么?

???

下面我们从头详细分析
1.首先看图1-1
图1-1
在这里插入图片我们可以看到这是美女吧的首页,图片已经标出了我们的目的,就是获取每个贴子中所有的美女图片。
当然了我们的目的不仅仅是这几个,而是本吧许许多多的内容,但是我们发现每页只有50名用户的贴子。
我们可以看到图中url,但是从这个url并不能分析出来多少多少页。我们尝试点击第二页第三页…会发现
第一页url变为了:https://tieba.baidu.com/f?kw=%E7%BE%8E%E5%A5%B3&ie=utf-8&pn=0
第二页url变为了:https://tieba.baidu.com/f?kw=%E7%BE%8E%E5%A5%B3&ie=utf-8&pn=50
第三页url变为了:https://tieba.baidu.com/f?kw=%E7%BE%8E%E5%A5%B3&ie=utf-8&pn=100
现在我们可以分析出每页的url都是遵循一定规则的就是pn后的值每次加50,那我们使用遍历的方法即可获得很多很多页数的内容。

2.我们随便点进一个贴子中(已打码,如有侵权请联系我,及时删除。)
可以看到图上面的url也是遵循一定规则的https://tieba.baidu.com/p/XXXXXXXXX
后面的XXXXXXXX就是每个账号的ID,我们继续尝试别的贴子,发现都是这种规律,那么我们就可以使用遍历的方式获取很多很多页的很多很多用户ID,就可以访问每位用户发的贴子内容,由此爬取每位用户发的图片。
图2-1
在这里插入图片描述
3.下面我们看图3-1
假设上面我的讲述你可以明白的话,那么看完这里你的思路应该就很明确了。
我们可以看到途中每个用户发的贴都在名为: “j_thread_list clearfix”的class标签下。
我们还获取了贴子的ID以及标题,那么我们马上就可以抓了,抓取发帖用户的ID,便于下面抓取该ID下的图片。
图3-1在这里插入图片描述
4.分析每位用户帖内的图片
好了,如果上面的内容都可以ok的话,看完这步就可以开始写代码了~
图4-1中的大黑框就是每个楼层信息,看底下的图片url,只要我们获取这个贴子中所有url就可以抓取图片了。
图4-1在这里插入图片描述

代码部分:

本次项目需要引入的模块,如果没有的话百度教程就ok很简单。

from pyquery import PyQuery
import os,time,requests

1.测试连通:

def get_requests(url):
    #网址
    # url="https://www.dbmeinv.com/?pager_offset=1"
    #请求头  --模拟浏览器--
    headers = {
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0"
    }        #设置一个头,更逼真模拟浏览器访问网页....但是再本次爬虫中到最后我才发现没有调用这个方法,只是再最开始的时候为了测试是否连接成功。
    html = requests.get(url=url, headers=headers).content
    return html

2.获取账号信息:

#获取账号信息
def get_account(html,listA):
    #加html数据
    html_py=PyQuery(html)
    #获取指定标签 下的内容 便于下面解析出路径
    item=html_py(".threadlist_title.pull_left.j_th_tit ").items()

    # global count
    for each in item:
        temp=[]
        url_img=each.find("a").attr("href")
        name=each.find("a").attr("title")
        # print("名称:%s   路径:%s"%(name,url_img))
        temp=[name,url_img]
        listA.append(temp)    #把抓取的所有发帖标题和发帖的ID存入列表中

3.获取图片

def get_image(html,account,name,path):
	#为了给获取的图片计数  引入全局变量count
    global count
    #加html数据
    html_py=PyQuery(html)
    #获取指定标签 下的内容 便于下面解析出路径
    item=html_py(".p_postlist")
    a=item(".d_post_content.j_d_post_content ").items()

    #获取图片url
    for i in a:
        url_image=i.find("img").attr("src")
        #判断 所获取的图片路径的有效性
        if url_image!=None and url_image[-3:]=="jpg":
            download_img_url=requests.get(url=url_image).content
            with open("%s/"%(path)+str(count)+".jpg","wb") as file:
                file.write(download_img_url)
                count+=1
                print("正在爬取%s的图片,第%s份数据。\n"%(account,count))
    #检测文件夹是否写入图片 若为空 则删除
    if not os.listdir("%s"%(path)):
        os.removedirs("%s"%(path))

4.主函数

def Main(count,listA):
    #listA  为了获取 用户账号
    for i in range(0,501,50):   #获取 十页 用户发出的贴子 url
        url=r"https://tieba.baidu.com/f?kw=%E7%BE%8E%E5%A5%B3&ie=utf-8&pn={}".format(i)
        #https://tieba.baidu.com/f?kw=%E7%BE%8E%E5%A5%B3&ie=utf-8&pn={} 美女吧
        #http://tieba.baidu.com/f?kw=%E5%A4%B4%E5%83%8F&ie=utf-8&pn={}  头像吧
        get_account(url,listA)

    #遍历出该账号在本吧 发的贴子url
    for i in range(len(listA)):
        url="http://tieba.baidu.com"+str(listA[i][1])

        #如果以账号命名的文件夹不存在 则创建
        if not os.path.exists("贴吧2/"+listA[i][1][3:]):
            os.makedirs("贴吧2/"+listA[i][1][3:])
        #进程相隔0.5秒 以免被拒绝访问   #我也不知道有没有实质作用,测试时发现如果没有进程睡眠这步的话大概获取70-100张图片就被禁止访问了,但是如果每次相隔0.5秒大概获取600张图片还没有被拒绝,或许是我的网络问题,可以自行测试。
        time.sleep(0.5)
        get_image(url,listA[i][1],listA[i][0],path="贴吧2/"+listA[i][1][3:])

#---------------------------------------美丽的分割线-------------------------------------------
count=0
listA=[]
Main(count,listA)   #调用主函数

5.全部代码:

import requests
from pyquery import PyQuery
import os,time
def get_requests(url):
    headers = {
        "User-Agent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:64.0) Gecko/20100101 Firefox/64.0"
    }
    # 请求网络数据 并解码
    html = requests.get(url=url, headers=headers).content.decode("utf-8")
    return html

#获取账号信息
def get_account(html,listA):
    #加html数据
    html_py=PyQuery(html)
    # print(html_py)
    item=html_py(".threadlist_title.pull_left.j_th_tit ").items()

    # global count
    for each in item:
        temp=[]
        url_img=each.find("a").attr("href")
        name=each.find("a").attr("title")
        # print("名称:%s   路径:%s"%(name,url_img))
        temp=[name,url_img]
        listA.append(temp)

#获取贴中  用户发的图
def get_image(html,account,name,path):
    global count
    #加html数据
    html_py=PyQuery(html)
    item=html_py(".p_postlist")
    a=item(".d_post_content.j_d_post_content ").items()

    #获取图片url
    for i in a:
        url_image=i.find("img").attr("src")
        if url_image!=None and url_image[-3:]=="jpg":
            download_img_url=requests.get(url=url_image).content
            with open("%s/"%(path)+str(count)+".jpg","wb") as file:
                file.write(download_img_url)
                count+=1
                print("正在爬取%s的图片,第%s份数据。\n"%(account,count))
    #检测文件夹是否写入图片 若为空 则删除
    if not os.listdir("%s"%(path)):
        os.removedirs("%s"%(path))

def Main(count,listA):
    #listA  为了获取 用户账号
    for i in range(0,501,50):
        url=r"https://tieba.baidu.com/f?kw=%E7%BE%8E%E5%A5%B3&ie=utf-8&pn={}".format(i)
        #https://tieba.baidu.com/f?kw=%E7%BE%8E%E5%A5%B3&ie=utf-8&pn={} 美女吧
        #http://tieba.baidu.com/f?kw=%E5%A4%B4%E5%83%8F&ie=utf-8&pn={}  头像吧
        get_account(url,listA)

    #遍历出该账号在本吧 发的贴子url
    for i in range(len(listA)):
        url="http://tieba.baidu.com"+str(listA[i][1])

        #如果以账号命名的文件夹不存在 则创建
        if not os.path.exists("贴吧2/"+listA[i][1][3:]):
            os.makedirs("贴吧2/"+listA[i][1][3:])
        #进程相隔0.5秒 以免免被拒绝访问
        time.sleep(0.5)
        get_image(url,listA[i][1],listA[i][0],path="贴吧2/"+listA[i][1][3:])

#---------------------------------------美丽的分割线-------------------------------------------
count=0
listA=[]
Main(count,listA)

#----------------------------------------------------------------更美的分割线------------------------------------------------------------------
程序实测:
在这里插入图片描述

写在最后:自学了几天爬虫,当看到自己写的代码可以运行并能获取到自己想要的东西后,非常的激动开心。第一次写博客教程(本人小白一枚),如有相关技术讲述错误,请提出我会及时更改,谢谢。
再次声明以上图片如有侵权请及时联系博主本人。

已标记关键词 清除标记
相关推荐
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页