爬虫实战02--python爬虫百度贴吧标题与图片,遇上反爬(JS渲染后的页面无法抓取),附解决方案,完整代码

01、运行环境

# 操作系统:win10 专业版
pycharm professional 2019.1
python 3.8
lxml == 4.5.1
requests == 2.23.0
xpath == 2.0.2

02、开始爬虫

02-1、爬取的内容

百度贴吧的标题以及里面的图片
在爬取的过程中遇上了反爬(JS渲染后的页面无法抓取。),附上解决方案。
地址:

url = https://tieba.baidu.com/f?kw=lol&ie=utf-8&tab=main&pn=0&

02-2、开始抓取内容

02-2-1、首先

在浏览器里面打开检查模式,然后用Google的擦肩Xpath去获取内容,再也中显示的是正常的,获取到了我们需要的内容。
在这里插入图片描述

02-2-2、接下来

我们就在pycharm里面编写代码,解析页面,基于lxml和xpath获取内容。下面是代码:

# 代码
# 爬取百度贴吧标题和图片
import requests
from lxml import etree

url = 'https://tieba.baidu.com/f?kw=lol&ie=utf-8&tab=main'

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36"
}

response = requests.get(url=url,headers=headers)
resstr = response.content.decode()

html = etree.HTML(resstr)
textlist = html.xpath("//ul/li//div[@class='threadlist_abs threadlist_abs_onlyline']/text()")

print(textlist)

02-2-3、没结果

但是获取的结果是空的列表。
在这里插入图片描述

02-3、JS渲染后的页面无法抓取

这里是一个空的列表,就是没有数据。检查过代码,逻辑,代码都是正确的,但是就是没有获取到数据。这就是我们遇到了反爬!!
-------(JS渲染后的页面无法抓取。)

所以接下来,我们就要去解决问题!

02-4、明确一点


重点—重点—重点—重点—重点—重点—
1、爬虫爬取页面不是以我们在页面右键检查看到的页面的。是以浏览器给我们返回的响应页面为爬取目标的!!!
重点—重点—重点—重点—重点—重点—


在这里插入图片描述
一般来说都是第一个刷新出来的。
是以f?开头的,这一个才是响应给我们的页面,我们爬取的就是这一个页面。

所以一切从头开始!!!

03、再次开始爬虫!~~

03-1、基础信息

url = https://tieba.baidu.com/f?kw=lol&ie=utf-8&tab=main&pn=0&

解决方案:
切换到手机端进行抓取。
同时把 User-Agent 也要改变!!!

# headers = {
#    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36"
}

# 我们现在切换到手机模式下面,这一个"User-Agent"也要响应的改变,
headers = {
     "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1"
 }

03-2、提取信息

03-2-1、提取文本

在这里插入图片描述

03-2-2、提取图像

在这里插入图片描述
这一个图像img标签src属性不是图片的地址,而后面的data-url才是真正的图片地址,切记不要采坑!~!!

04、完整代码(面向对象版)

import requests
from lxml import etree


class TiebaSpider(object):
    """百度贴吧爬虫类"""

    def __init__(self, word, max_page):
        # 目标URL地址
        # https://tieba.baidu.com/f?ie=utf-8&kw=lol&fr=search&pn=0&
        # 200最大数量 =  0 50 100 150 200
        self.base_url = "https://tieba.baidu.com/f?ie=utf-8&kw={}&fr=search&pn={}&"

        # 构建请求头
        # 电脑端口的请求头,失败!
        # self.headers = {
    		# "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.125 Safari/537.36"
		# }
        # 手机端的请求头!
        self.headers = {
            "User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1",
        }

        # 搜索关键字
        self.word = word

        # 爬取的最大数量
        self.max_page = max_page

    def get_urls(self):
        """拼接url地址,添加到列表中"""

        url_list = [self.base_url.format(self.word, page) for page in range(0, self.max_page, 50)]
        return url_list

    def send_request(self, url):
        """发送get请求,获取响应"""

        response = requests.get(url=url, headers=self.headers)
        return response.content.decode()

    def get_content(self, html):
        """先分组,然后再提取数据"""

        # 1.将html转换成xpath对象
        eroot = etree.HTML(html)

        # 2.利用xpath语法规则提取li标签列表
        li_list = eroot.xpath("//li[@class='tl_shadow tl_shadow_new ']")
        # print(li_list)

        # 3.遍历每一个li标签提取,贴吧标题和图片列表
        item_list = []
        for li in li_list:
            item_dict = {}

            # 提取标题
            # 去除字符串前后的空格:strip()
            item_dict["title"] = li.xpath('.//div[@class="ti_title"]/span/text()')[0].strip() if len(li.xpath('.//div[@class="ti_title"]/span/text()'))>0 else None
            # 提取图片信息
            item_dict["imgs"] = li.xpath('.//img[@class="j_media_thumb_holder medias_img medias_thumb_holder"]/@data-url') if len(li.xpath('.//img[@class="j_media_thumb_holder medias_img medias_thumb_holder"]/@data-url')) > 0  else []

            item_list.append(item_dict)

        print(item_list)

    def run(self):
        # 1.构建url
        url_list = self.get_urls()
        print(url_list)
        for url in url_list:
            # 2.发送请求,获取响应
            html = self.send_request(url)
            # 3.使用xpath语法提取响应中的数据[贴吧标题 & 图片列表]
            self.get_content(html)


if __name__ == '__main__':
    spider = TiebaSpider("lol", 200)
    spider.run()

最后获取的信息是以打印的方式展现的!

05、结语:

个人记录,新手入门,多多学习,欢迎大家交流探讨!
个人网站: http://106.54.78.238/
song_of _sea的个人网站 http://106.54.78.238/

猜你喜欢

转载自blog.csdn.net/weixin_44824717/article/details/108130777