in

如何在2024年爬取Facebook数据

爬取Facebook数据

这是一个逐步示例,展示如何使用Python爬取公开可用的Facebook数据。

企业收集Facebook数据以进行情感和竞争对手分析,保护其在线声誉或寻找影响者。然而,该平台对于爬虫是不友好的 – 从IP封锁到速率限制,如果没有正确的工具和知识,数据收集可能变得繁琐。
在本指南中,您将学习如何合法地爬取Facebook数据,需要哪些工具才能获得高成功率,并且如何避免IP地址被封禁。此外,我们还将为您提供使用基于Python的爬虫程序来爬取Facebook页面的实际示例。

什么是 Facebook 爬取 – 定义

Facebook 爬取是一种自动从社交媒体平台收集数据的方法。人们通常使用预制的网络爬取工具或定制的爬取工具来爬取 Facebook 数据。然后,对收集到的数据进行解析(清理)并导出为易于分析的格式,例如 .json。

通过爬取帖子、点赞或关注者等数据点,企业可以收集客户意见、分析市场趋势、监控在线品牌推广工作并保护其声誉。

Facebook 爬取合法吗?

尽管社交媒体平台可能不喜欢网络爬取,但收集公开数据的行为是合法的。2022 年,第九巡回上诉法院裁定,爬取公共数据并不违反《计算机欺诈和滥用法》。

然而,这并不能阻止 Facebook 的所有者 Meta 积极打击任何从其平台窃取数据的人, 从新裁决后不久该公司针对爬虫提起的诉讼来看。看来 Meta 将继续为保持其信息垄断而奋斗。

那么,您可以爬取哪些 Facebook 数据?

首先也是最重要的,如果您想爬取社交媒体数据,您需要确保它 1) 公开,并且 2) 不受版权法保护。以下是 Facebook 上主要公开的类别:

  • 个人资料:最新帖子、用户名、个人资料URL、个人资料照片URL、关注者和粉丝、点赞和兴趣以及包括在个人资料中的其他公开信息。
  • 帖子:最新帖子、日期、位置、点赞、浏览次数、评论、文本和媒体URL。
  • 标签:帖子URL、媒体URL、帖子作者ID。
  • Facebook商业页面:URL、个人资料图片、名称、点赞、故事、关注者、联系信息、网站、类别、用户名、头像、类型、已验证、相关页面信息。

如果您将收集个人信息(这很可能),则会适用更多规则,例如需要通知该人并给予他们选择退出的权利。最好咨询律师,以确保您的操作合法。

如何选择 Facebook 爬取工具

Facebook 爬取的一种方法是使用Selenium 和 Playwright等框架构建自己的爬取工具。两者都是控制无头浏览器的流行工具,对于爬取 Facebook 来说是必需的。然而,该平台对爬虫不利,因此自建工具最适合中级到高级用户。

一个更简单的解决方案是使用预制的爬虫。让我们以 Facebook-page-scraper 为例。它是一个 Python 包,旨在爬取 Facebook 页面的前端。此类爬取工具已经包含提取和构建相关数据的逻辑。 然而,如果没有额外的工具(例如有助于掩盖网络爬取工具数字指纹的代理),它们就无法工作。

最直接的选择是购买商业网络爬取工具。 根据您的技术知识和需求,有多种选项可供选择:

  1. 如果您不想涉及代码,可以选择无代码爬虫。服务如Parsehub、PhantomBuster或Octoparse提供的爬虫允许您通过单击可视元素来提取数据。它们非常适合小规模数据收集或在不需要运行复杂设置时使用。
  2. 或者,您可以获取一个网络爬虫API。它们类似于预制的网络爬虫,但维护更好,并且内置了所有必要的元素。因此,您只需要发送请求并存储输出。像Smartproxy或Bright Data这样的公司都提供可以爬取Facebook的API。

何爬取 Facebook 帖子:使用 Python 的分步示例

在此示例中,我们将使用基于 Python 的爬取工具 – Facebook-page-scraper 3.0.1。它预先编写了大部分网络爬取逻辑,不限制您可以发出的请求数量,并且您不需要注册或拥有 API 密钥。

开始爬取 Facebook 的必要工具

为了使爬取工具正常工作,您需要使用代理服务器和无头浏览器库。

Facebook 对爬取工具采取了各种行动,从请求限制到 IP 地址封锁。代理可以通过屏蔽您的 IP 地址和位置来帮助规避这种结果。如果您不知道在哪里可以找到优质 IP,我们列出了最佳Facebook 代理提供商列表 。

我们需要一个无头浏览器有两个原因。首先,它将帮助我们加载动态元素。其次,由于 Facebook 使用反机器人保护,它将使我们能够模仿真实的浏览器指纹。

管理期望

在进入代码之前,您需要了解一些事情。

Facebook 爬取工具仅限于公开可用的数据。我们不鼓励您在登录后爬取数据,但有些人可能会发现这是一个缺点。

最近,Facebook 进行了一些更新,影响了我们将使用的爬取工具。如果您想爬取多个页面或避免出现 cookie 同意提示,则必须对爬取文件进行一些调整。但别担心——我们会指导您完成每一步。

如果您想了解有关网络爬取的更多详细信息,请查看我们指南中的最佳网络爬取实践

预备工作

在开始之前,您需要拥有 Python 和 JSON 库。然后,您需要安装 Facebook-page-scraper。  您可以通过在终端中输入 pip install 命令来完成此操作:

pip install facebook-page-scraper

代码的修改

现在,让我们对 scraper 文件进行一些更改。

为了避免出现 cookie 同意提示,您首先需要修改driver_utilities.py文件。否则,爬取工具将继续滚动提示,而您将不会得到任何结果。

步骤1 在控制台中使用 show 命令查找文件。它将返回保存文件的目录。

pip show facebook_page_scraper

步骤2 现在,在driver_utilities.py中,将代码添加到wait_for_element_to_appear定义的末尾。

allow_span = driver.find_element(
            By.XPATH, '//div[contains(@aria-label, "Allow")]/../following-sibling::div')
        allow_span.click()

整个函数如下所示:

@staticmethod
    def __wait_for_element_to_appear(driver, layout):
        """expects driver's instance, wait for posts to show.
        post's CSS class name is userContentWrapper
        """
        try:
            if layout == "old":
                # wait for page to load so posts are visible
                body = driver.find_element(By.CSS_SELECTOR, "body")
                for _ in range(randint(3, 5)):
                    body.send_keys(Keys.PAGE_DOWN)
                WebDriverWait(driver, 30).until(EC.presence_of_element_located(
                    (By.CSS_SELECTOR, '.userContentWrapper')))
            elif layout == "new":
                WebDriverWait(driver, 30).until(
                    EC.presence_of_element_located((By.CSS_SELECTOR, "[aria-posinset]")))
        except WebDriverException:
            # if it was not found,it means either page is not loading or it does not exists
            print("No posts were found!")
            Utilities.__close_driver(driver)
            # exit the program, because if posts does not exists,we cannot go further
            sys.exit(1)
        except Exception as ex:
            print("error at wait_for_element_to_appear method : {}".format(ex))
            Utilities.__close_driver(driver)
        allow_span = driver.find_element(
            By.XPATH, '//div[contains(@aria-label, "Allow")]/../following-sibling::div')
        allow_span.click()
步骤3 如果您计划同时爬取多个页面,必须修改scraper.py文档。此更新将从不同的爬取目标中分离信息到单独的文件中。

步骤4。继续修改scraper.py文件以支持从多个页面中爬取信息并将其保存到单独的文件中。

  1. 将以下行移动到init()方法中,并在这些行的开头添加self参数,以便可以实例化这些变量。

这将使数据字典和已提取帖子的集合在每个实例中都可用。

更新后的scraper.py文件应如下所示:

from webdriver_utilities import Utilities
from page_utilities import Pages
from page_utilities import PagesType
from time import sleep
from random import randint
from datetime import datetime
import os
import json
import sys

class Scraper:
    def __init__(self, page_name, number_of_posts, browser="chrome", proxy=None, timeout=60, headless=True):
        self.__page_name = page_name
        self.__number_of_posts = number_of_posts
        self.__browser = browser
        self.__proxy = proxy
        self.__timeout = timeout
        self.__headless = headless
        self.__current_path = os.path.dirname(os.path.realpath(__file__))
        self.__data_dict = {}
        self.__extracted_post = set()

    def scrap(self):
        try:
            # Initialize the web driver
            driver = Utilities.get_driver(
                self.__browser, self.__proxy, self.__headless)
            Utilities.go_to_url(
                driver, Pages.get_url(self.__page_name, PagesType.PAGE))
            Utilities.__scroll_page(
                driver, self.__number_of_posts // 10, self.__page_name)
            
            # Rest of the scraping logic here...

        except Exception as ex:
            print(f"An error occurred: {str(ex)}")
        finally:
            Utilities.__close_driver(driver)

    # Other methods...

步骤5。现在,您可以在scraper.py中添加一个新的方法,以将数据保存到单独的文件中。

在Scraper类中添加一个新的方法,用于将数据保存到文件中。我们将这个方法命名为save_to_file。这个方法将接受一个文件名作为参数,并将数据保存到以该文件名为名称的JSON文件中。

def save_to_file(self, filename):
    if not filename.endswith('.json'):
        filename += '.json'

    try:
        with open(filename, 'w', encoding='utf-8') as file:
            json.dump(self.__data_dict, file, ensure_ascii=False, indent=4)
        print(f"Data saved to {filename}")
    except Exception as ex:
        print(f"An error occurred while saving data: {str(ex)}")

步骤6。现在,您可以在scraper.py中修改scrap方法,以在爬取完毕后调用save_to_file方法。

在Scraper类的scrap方法中,添加一行代码,以在爬取完毕后调用save_to_file方法,将数据保存到文件中。您可以选择在任何方便的时候调用此方法,但在示例中,我们将其放在数据爬取完成后。

def scrap(self):
    try:
        # Initialize the web driver
        driver = Utilities.get_driver(
            self.__browser, self.__proxy, self.__headless)
        Utilities.go_to_url(
            driver, Pages.get_url(self.__page_name, PagesType.PAGE))
        Utilities.__scroll_page(
            driver, self.__number_of_posts // 10, self.__page_name)
        
        # Rest of the scraping logic here...

        # Save data to file
        self.save_to_file(f'{self.__page_name}_data')
    except Exception as ex:
        print(f"An error occurred: {str(ex)}")
    finally:
        Utilities.__close_driver(driver)

# Other methods...

步骤7。最后,您可以在您的主程序中使用新的Scraper类来爬取数据并将其保存到文件中。在主程序中,您首先需要创建一个Scraper实例,然后调用其scrap方法来执行爬取和保存操作。

# Import the Scraper class from scraper.py
from scraper import Scraper

# Define the page name, number of posts, and other parameters
page_name = 'example_page'
number_of_posts = 100  # Change this to the desired number of posts
browser = 'chrome'  # You can change the browser if needed
proxy = None  # Add your proxy configuration if necessary
timeout = 60  # Adjust the timeout as needed
headless = True  # Set to False if you want to see the browser in action

# Create a Scraper instance
scraper = Scraper(page_name, number_of_posts, browser, proxy, timeout, headless)

# Call the scrap method to start scraping
scraper.scrap()

# The data will be saved to a JSON file automatically

这样,您就可以使用新的Scraper类轻松爬取数据并将其保存到单独的JSON文件中。只需在主程序中设置适当的参数,然后调用scrap方法即可。希望这些步骤有助于您成功地爬取Facebook数据并保存到文件中.

总结

完整的如何在2024年爬取Facebook数据的代码示例

# 导入所需的库和模块
from webdriver_utilities import Utilities
from page_utilities import Pages, PagesType
from time import sleep
from random import randint
from datetime import datetime
import os
import json
import sys

# Scraper 类用于爬取 Facebook 数据
class Scraper:
    def __init__(self, page_name, number_of_posts, browser="chrome", proxy=None, timeout=60, headless=True):
        self.__page_name = page_name
        self.__number_of_posts = number_of_posts
        self.__browser = browser
        self.__proxy = proxy
        self.__timeout = timeout
        self.__headless = headless
        self.__current_path = os.path.dirname(os.path.realpath(__file__))
        self.__data_dict = {}
        self.__extracted_post = set()

    def scrap(self):
        try:
            # 初始化 Web 驱动程序
            driver = Utilities.get_driver(
                self.__browser, self.__proxy, self.__headless)
            Utilities.go_to_url(
                driver, Pages.get_url(self.__page_name, PagesType.PAGE))
            Utilities.__scroll_page(
                driver, self.__number_of_posts // 10, self.__page_name)
            
            # 其余的爬取逻辑在这里...

            # 将数据保存到文件
            self.save_to_file(f'{self.__page_name}_data')
        except Exception as ex:
            print(f"发生错误: {str(ex)}")
        finally:
            Utilities.__close_driver(driver)

    def save_to_file(self, filename):
        if not filename.endswith('.json'):
            filename += '.json'

        try:
            with open(filename, 'w', encoding='utf-8') as file:
                json.dump(self.__data_dict, file, ensure_ascii=False, indent=4)
            print(f"数据已保存至 {filename}")
        except Exception as ex:
            print(f"保存数据时发生错误: {str(ex)}")

# 主程序
if __name__ == "__main__":
    # 定义页面名称、要爬取的帖子数量和其他参数
    page_name = 'example_page'
    number_of_posts = 100  # 更改为所需的帖子数量
    browser = 'chrome'  # 如有需要,可以更改浏览器
    proxy = None  # 如果需要,添加代理配置
    timeout = 60  # 根据需要调整超时时间
    headless = True  # 如果想要查看浏览器操作,设置为 False

    # 创建 Scraper 实例
    scraper = Scraper(page_name, number_of_posts, browser, proxy, timeout, headless)

    # 调用 scrap 方法开始爬取
    scraper.scrap()

常见问题解答(FAQs)

Q1:我如何更改要爬取的页面和帖子数量?

在主程序的page_namenumber_of_posts变量中设置所需的页面名称和帖子数量。

Q2:如何更改浏览器和代理配置?

您可以在主程序中的browserproxy变量中设置浏览器类型和代理配置,以满足您的需求。

Q3:如何调整超时时间?

timeout变量中设置所需的超时时间(以秒为单位)。

Q4:我可以看到浏览器操作吗?

如果要查看浏览器操作,请将headless变量设置为False。否则,将其保持为True以在后台运行。

Q5:数据将保存在哪个文件中?

数据将保存在与页面名称相关的JSON文件中,文件名为page_name_data.json

希望这些信息有助于您成功地爬取Facebook数据。如果您有任何其他问题,请随时提问。请注意,爬取Facebook数据时需要遵守法律和Facebook的政策,并仅爬取公开可用的数据。

What do you think?

68

Written by 砖家

68web团队是一支专注于跨境业务和数据获取的专业团队。我们致力于帮助企业成功出海,通过高效的数据爬取服务,为客户提供精准的数据支持;

凭借丰富的经验和专业的技术,我们不仅提供多语言网站建设,还包括国际市场推广和定制化的跨境电商解决方案;

我们的数据爬取平台利用强大的服务器和代理IP,确保获取高质量的数据,以满足客户在AI和大数据时代的需求。我们专注于提供全面的解决方案,助力企业在全球市场上取得成功。

合法使用爬虫搜集数据

网页抓取合法吗?如何合法使用爬虫搜集数据

Beautifulsoup爬取多个页面

如何使用Beautifulsoup爬取多个页面?