python爬虫之Beautifulsoup和Scrapy框架的协同工作

最近在开始做关于百度贴吧爬虫时,遇到了xpath解析贴吧网页死活解析不出来的情况,试了火狐和Chrome浏览器都是这样,愤怒之下选择了使用BeautifulSoup框架,(百度出来的,我是个初学者),折腾了半天总算解析出来一些期望的数据,贴上一些个人遇到的坑和总结的经验:

# -*- coding: utf-8 -*-
import scrapy
from bs4 import BeautifulSoup
import re
import urllib
# import  requests
# from copy import  deepcopy


class TiebaSpider(scrapy.Spider):
    name = 'tieba'
    allowed_domains = ['tieba.com']
    start_urls = ['https://tieba.baidu.com/f?kw=%C0%EE%D2%E3&fr=ala0&tpl=5']
    # 这个对应的是手机版极速模式的李毅吧爬虫,电脑版的不好做,做手机版的需要改浏览器的User-Agent,
    # 火狐上需要装个插件叫UserAgent Switcher即可实现修改

    def parse(self, response):
        # 根据帖子进行分组
        # 网页的内容保存在response的body属性中,之前一直以为在response中
        # response具体是什么,直接print出来即可
        content = BeautifulSoup(response.body, 'lxml')
        div_list = content.find_all(attrs={'class': re.compile("i.*")})
        # print(div_list)
        for div in div_list:
            if div.a is not None:
                # 正常的div数据类型都是BeautifulSoup中的tag标签,\
                # 可以直接对div.a进行索引取链接的,但是有部分老鼠屎div.a是空的(可能是由于\
                # 没有选取好attrs的匹配条件),因此 进行一个非空判断,否则在运行时就会报错:\
                # TypeError: 'NoneType' object is not subscriptable
                item = {}
                # 打印出div.a的类型,发现其中有部分数据是None类型的
                # print(type(div.a))
                item["href"] = div.a["href"]
                # urllib.parse.urljoin()函数后还能够自动根据response的url补全对应的url地址
                item["href"] = urllib.parse.urljoin(response.url, item["href"])  # 取链接地址
                item["title"] = div.a.string    # 取标签对应的内容,即帖子的名字
                item["img_href"] = []   # 整个空列表,无论之后是第几页的图片链接,都直接使用
                # extend()函数进行追加,如此就可以防止前一页的图片链接数据被后一页的图片链接所覆盖

                yield scrapy.Request(
                       item["href"],
                       callback=self. parse_detail,  # 注意此处是函数名,没有加括号,加了括号就成了函数调用
                       meta={"item": item},
                       dont_filter=True  # 此处必须设置dont_filter,否则这些贴吧页面对应的请求会被过滤掉
                       # 怎么查看是被过滤掉:我在下面的parse_detail()函数中打印response没有任何结果,参照下面
                       # 的链接查出来的:https://blog.csdn.net/mr_hui_/article/details/80435941
                       # 至于为什么被过滤掉,我就是个菜鸡我也不知道
                )

        # 列表页翻页
        content = BeautifulSoup(response.body, 'lxml')
        if content.find(text="下一页") is not None:
            next_url_tag = content.find(text="下一页").parent
            next_url = next_url_tag["href"]
            next_url = urllib.parse.urljoin(response.url, next_url)  # 补全下一页的URL地址
            # print(next_url)
            yield scrapy.Request(
                next_url,
                callback=self.parse,
                dont_filter=True
            )

    # 处理帖子详情页中的图片
    def parse_detail(self, response):
        item = response.meta["item"]
        # if response is not None:
        #     print(response)
        # else:
        #     print("空响应")
        content2 = BeautifulSoup(response.body, 'lxml')
        
        image_list = content2.find_all(href=re.compile("http://.+\.jpg"))
        for imge_src in image_list:
            # print(imge_src["href"])
            # 防止下一页的图片链接覆盖掉上一页图片的链接,采用追加
            # print(imge_src["href"])
            item["img_href"].extend(imge_src["href"])
            with open("./imag_link.txt", "a+") as file:
                file.write(imge_src["href"] + "\n")
        if content2.find(text="下一页") is not None:   # 注意非空判断,否则又会报错
            next_url_tag = content2.find(text="下一页").parent  # 根据文本内容为下一页找对应的标签
            next_url = next_url_tag["href"]
            next_url = urllib.parse.urljoin(response.url, next_url)  # 补全下一页的URL地址
            if next_url is not None:
                yield scrapy.Request(
                    next_url,
                    callback=self.parse_detail,
                    meta={"item": item},
                    dont_filter=True
                )

上述代码只能爬取出来一部分内容,无法完全爬出来,我也不知道哪里出问题了(尴尬),对应的项目中setting.py我只是做了如下修改:

LOG_LEVEL = "WARNING"
USER_AGENT = "Mozilla/5.0 (Android 7.0; Mobile; rv:61.0) Gecko/61.0 Firefox/61.0"
# Obey robots.txt rules
ROBOTSTXT_OBEY = False

找不出来bug很难受,哪位大佬若发现了,请多指教,在此先谢过

BeautifulSoup框架教程地址:https://www.crummy.com/software/BeautifulSoup/bs4/doc.zh/

猜你喜欢

转载自blog.csdn.net/qq_15054345/article/details/86896568