webelement 获取span class_爬虫(六)爬取任意贴吧,获取标题、详情页地址及图片(手机版)...

00fc832c6d33a0d0a39c0f4ab8afb64b.png

工具:python 3.7.3 、Chrome 、PyCharm

爬取过程

一、安装库:

1.requests模块

在python2 和python3中通用,方法完全一样,简单易用,能够自动帮助我们解压(gzip压缩的等)网页内容。

response = requests.get(url, headers=headers)

2.json模块

实现json数据和python内建数据格式的相互转换

f.write(json.dumps(content,ensure_ascii=False))

3.re模块

Python提供re模块,包含所有正则表达式的功能,正则表达式是一种用来匹配字符串的强有力的武器。

re.findall(""total_page":(d+),",html_str)

4.LXML类库

lxml是一款高性能的 Python HTML/XML 解析器,我们可以利用XPath,来快速的定位特定元素以及获取节点信息。导入lxml的etree库,利用etree.HTML,将字符串转化为Element对象,Element对象具有xpath的方法。

html=etree.HTML(html_str)

二、爬取

1.分析

Chrome浏览器中打开百度贴吧进入任意贴吧,打开检查点击Network下的Preview寻找包含响应的url。依次查看左侧除图片和Js外的响应发现贴吧信息在以f?ie=utf-8开头的响应中。但是发现需要的信息都被注释起来了,尝试进入手机版网页获取响应,贴吧信息同样在以f?ie=utf-8开头的响应中。

a87ea3e4696217053863a9efc7c4c0f5.png

3c51be0a3fe6d90f0173a535b03ea66e.png

观察响应为html,为静态网页,静态网页可以采取正则表达式、xpath等方法进行爬取。进行xpath爬取时借助Chrome插件 XPath Helper

改变贴吧名字和页码数观察url变化,发现改变参数kw的值可以切换贴吧,改变pn的值实现翻页,pn为从0开始公差为50的等差数列。

d1081698ba399bbe63c95badd4c41f9c.png

爬取任意贴吧,不清楚每个贴吧总页数,观察页面响应发现下一页url地址为#,提取不到,因而准备初始url地址,发送请求获取响应,提取数据和页面总数total_page并将数据保存,循环构造下一页url地址,发送请求获取响应,提取信息并保存的过程,直到pn大于(total_page-1)*50。

af042c11b5eeadc4c288821dcad1241a.png

列表页可以获取到每个帖子的标题,也可以获取详情页url,获取详情页url后,发送请求获取响应,提取详情页图片,最后将提取数据结果放在字典中,以列表的形式返回。

b92a24de4675a6f030cafeb0cbf4160b.png

26a4dc99af884be559396b2fe3636ea9.png

每个帖子数据在li标签下,xpath提取帖子列表li_list,遍历列表获取每个帖子的数据

121a7954ee7a338c9631164d4eaab832.png

列表页标题内容在帖子列表li_list下的a标签下的span标签下,xpath提取文本数据

0cb200f0ed9c8cafab7fdd2b3a50d019.png

详情页url地址在帖子列表li_list下的a标签,xpath提取href属性。观察到详情页url地址不完整,需要补全

a0885c08faee8fbb62fe6157f217037c.png

详情页图片在详情页响应span标签下的div标签,xpath提取data-url属性

f53e16e44d022248edf1fde633b39577.png

页面总数total_page在列表页响应中,使用正则表达式提取

a26319cb5ba9cfc0f5aa7e344022e788.png

2.代码

import requests
from lxml import etree
import json
import re

class BaiduTieba:
    def __init__(self,tiebaname):
        self.tiebaname=tiebaname
        self.start_url_temp="https://tiebac.baidu.com/mo/q/m?word="+tiebaname+"&page_from_search=index&tn6=bdISP&tn4=bdKSW&tn7=bdPSB&lm=16842752&lp=6093&sub4=%E8%BF%9B%E5%90%A7&pn={}"
        self.headers={"User-Agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 11_0 like Mac OS X) AppleWebKit/604.1.38 (KHTML, like Gecko) Version/11.0 Mobile/15A372 Safari/604.1"}
    def parse_url(self,url):
        response=requests.get(url,headers=self.headers)
        # print(response.content.decode())
        return response.content.decode()

    def get_content_list(self, html_str):
        html=etree.HTML(html_str)
        li_list = html.xpath("//ul[@id='frslistcontent']/li[@class='tl_shadow tl_shadow_new ']")#分组
        content_list=[]
        for li in li_list:
            item={}
            item["title"]=li.xpath(".//a/div[@class='ti_title']/span/text()")[0] if len(li.xpath(".//a/div[@class='ti_title']/span/text()"))>0 else None
            item["href"]=li.xpath(".//a/@href")[0] if len(li.xpath(".//a/@href"))>0 else None #详情页url
            item["href"]="https://tieba.baidu.com"+item["href"] #详情页url地址不完整,补充
            item["img_list"]=self.get_img_list(item["href"]) #将详情页图片放入字典中
            content_list.append(item)
            print(content_list)
        total_page=int(re.findall(""total_page":(d+),",html_str)[0])
        return content_list,total_page
    def get_img_list(self,detail_url):
        html_str=self.parse_url(detail_url)
        html=etree.HTML(html_str)
        img_list=html.xpath("//span[@class='wrap pbimgwapper']/div/@data-url")
        return img_list
    def save_content_list(self,content_list):
        file_path=self.tiebaname+".txt" #以贴吧名保存文件
        with open(file_path,"a",encoding="utf-8") as f:
            for content in content_list:
                f.write(json.dumps(content,ensure_ascii=False,indent=3))
                f.write("n")
        print("保存成功")
    def run(self):
        num=0
        total_page=100
        while num<=(total_page-1)*50:
            url = self.start_url_temp.format(num)
            html_str=self.parse_url(url)
            content_list,total_page=self.get_content_list(html_str)
            self.save_content_list(content_list)
            num=num+50

if __name__=="__main__":
    baidutieba=BaiduTieba("李毅")
    baidutieba.run()

三、结果及出现问题

1.结果

fd3589dd9939fbd725fc0ddda4a45291.png

2.问题

  • 注意对照element和响应是否一致,不一致时以响应信息为准。
    提取详情页图片时,element下图片在img标签下属性class为BDE_Image,需xpath提取src属性

bcd8199360012cf7c5d8f0719fea2cd1.png


而响应信息里图片在详情页响应span标签下的div标签,xpath提取data-url属性

f53e16e44d022248edf1fde633b39577.png


如果按照element的信息提取,img_list将为空。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值