Python爬虫,爬取百度贴吧图片和视频文件,xpath+lxml,访问被拒的原因分析

目录

百度贴吧图片和视频文件爬取程序

1.需求分析

2.url分析

3.Xpath分析

4.程序设计

5.坑点


百度贴吧图片和视频文件爬取程序

1.需求分析

进入百度贴吧,搜索周杰伦,进入周杰伦吧。我们的目的是爬取图片文件和视频。下面是首页文件,如果我们要爬取图片或视频文件的话,第一步是爬取该页面下的所有帖子的url,进入到这些帖子后,再进行图片和视频爬取。

 

2.url分析

1)百度贴吧首页url分析

经过初步分析,我发现百度贴吧的url为:http://tieba.baidu.com/f?kw=周杰伦pn=0

kw是搜索内容,pn是页码,第一页为0,第二页为50,所以页码的公式为pn=(页数-1)*50

2)帖子url分析

经分析,发现帖子的链接只有一小段,百度采用的是相对路径的方式。

 点击进入帖子,发现帖子的Url为:http://tieba.baidu.com/p/6130726976

也就是说帖子完整的url:http://tieba.baidu.com/+帖子href属性里的值

 

3.Xpath分析

如果对Xpath不熟的可以去看我另一篇文章,里面有Xpath的教学:https://blog.csdn.net/ck784101777/article/details/104291634

分析完url后,接下来分析如何提取贴子的url和图片、视频的url。

我是通过右键进入检查页面,来进行分析的。按图中步骤来做就可。

1)帖子Xpath分析

进过分析,很容易的得帖子的Xpath://div[@class="threadlist_title pull_left j_th_tit"]/a/@href

只需要定位到a标签的父节点div的class属性值,再提取a的href属性值即可

 

2)图片Xpath分析

分析后得出Xpath://div[@class="d_post_content j_d_post_content clearfix"]/img[@class="BDE_Image"]/@src

3)视频Xpath分析

一开始我写Xpath时的时候,是按照下图来写的,写出来的格式为://div[@class="video_src_wrap_main"]/video/@src

结果发现死活爬不到。然后我去分析响应源码。

发现在拿到响应文件后,视频格式有变化,按照这个变化,我写出的Xpath为:

//div[@class="video_src_wrapper"]/embed/@data-video

 

总结:

1.帖子Xpath://div[@class="threadlist_title pull_left j_th_tit"]/a/@href

2.图片Xpath://div[@class="d_post_content j_d_post_content clearfix"]/img[@class="BDE_Image"]/@src

3.视频Xpath://div[@class="video_src_wrapper"]/embed/@data-video

 

4.程序设计

程序整体的结构如下:

1.download_srcs()函数:该函数为核心函数,它首先把每个帖子的url获取到,然后进入到每个帖子去爬图片和视频

2.save_local()函数:这个函数时把图片和视频文件下载到本地,由download_srcs()调用

3.get_html()函数:功能函数,作用是获取html页面内容

4.get_Xpath()函数:功能函数,作用是获取xpath的匹配的列表

5.run()函数:启动函数,为程序的入口

from lxml import html
from urllib import parse
import random
import time
import requests

class BaiduImgandVedio_spider(object):
    def __init__(self):
        self.url="http://tieba.baidu.com/f?kw={}&pn={}"
        self.headers="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36"
        self.dir="C:\\Users\\Administrator\\Desktop\\新建文件夹\\"

    #获取html页面的内容
    def get_html(self,url):
        html=requests.get(url=url,headers={"User-Agent":self.headers},timeout=3).text
        return html

    #获取xpath封装的结果
    def get_Xpath(self,rep,xpath_regex):
        p=html.etree.HTML(rep)
        result=p.xpath(xpath_regex)
        return result

    #下载图片或视频到本地
    def download_srcs(self,url):
        html=self.get_html(url)
        #这里有一个坑,xpath无法匹配注释文件里的的内容,我们下载的文件是带注释的,所以这里去除注释
        html=html.replace("<!--","")
        #获取帖子的url列表
        xpath_tiezi='//div[@class="t_con cleafix"]/div/div/div/a/@href'
        tiezi_lists=self.get_Xpath(html,xpath_tiezi)
        #循环遍历被一个帖子
        for i in tiezi_lists:
            #获取到的uri类似p/6491314161,所以还要进行拼接
            tiezi_url="http://tieba.baidu.com/"+i
            tiezi_html=self.get_html(tiezi_url)
            tiezi_html=tiezi_html.replace("<!--","")
            #图片和视频的xpath
            xpath_imgorvedio='//img[@class="BDE_Image"]/@src | //div[@class="video_src_wrapper"]/embed/@data-video'
            #调用Xpath解析方法,获得图片和视频的url
            imgorvedio_urls=self.get_Xpath(tiezi_html,xpath_imgorvedio)
            #下载到本地
            self.save_local(imgorvedio_urls)
    
    #保存到本地
    def save_local(self,urls):
        for i in urls:
            imgordedio_html=requests.get(url=i,headers={"User-Agent":self.headers},timeout=10).content
            #切割后10位
            filename=i[-10:]
            dir=self.dir+filename
            print(dir)
            with open(dir,"wb") as f:
                f.write(imgordedio_html)
            time.sleep(random.randint(0,1))
            print(filename,"下载成功")
    
    #函数入口
    def run(self):
        word=input("请输入关键词:")
        begin=int(input("请输入起始页:"))
        end=int(input("请输入终止页:"))
        #字符转编码
        name=parse.quote(word)
        for i in range(begin,end):
            #获取页码数
            i=(begin-1)*50
            url=self.url.format(name,i)
            #调用download函数
            self.download_srcs(url)

if __name__=="__main__":
    spdier=BaiduImgandVedio_spider()
    spdier.run()

效果:

 

 

5.坑点

1)样式是变化的,xpath可能失效

本程序有很多坑点,最大的坑点就在于xpath,由于百度贴吧的样式(class属性)不是一成不变的,我可能今天这么写可以成功,但是以后改动后这个程序就爬不到了,所以如果你执行这个程序没有爬到数据,需要自己去改xpath,分析流程请按照我文章所讲的去做。

2)垃圾图片

另外一个坑点就在于爬取到的图片和视频有很多垃圾图片,这个是没办法的,xpath的匹配结果是模糊匹配,不可能帮你识别图片是否垃圾图片,这里指的垃圾图片是与内容无关的,比如我想爬周杰伦的图片却给我爬出一些广告图片。

3)访问被拒

访问被拒有可能是你的User-Agent问题,这里推荐用一个动态的User-Agent,也就是不要用一成不变的,你可以做一个User-Agent池,每次发请求时用一个随机数获取池中的一条Agent。

如果你的ip因为爬虫被封了,你可以尝试用代理ip去爬,网上代理ip一大堆,当然,如果是免费的代理ip是非常不好用的,如果你想用好一点的代理ip,可以去专门卖代理ip的网站上去买,价格不贵。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值