使用 Scrapy 抓取 Python 数据

2023-11-21

我想从具有文本字段、按钮等的网站中抓取数据。我的要求是填写文本字段并提交表单以获取结果,然后从结果页面中抓取数据点。

我想知道Scrapy有这个功能或者是否有人可以推荐一个Python库来完成这个任务?

(edited)
我想从以下网站抓取数据:
http://a836-acris.nyc.gov/DS/DocumentSearch/DocumentType

我的要求是从组合框中选择值,然后单击搜索按钮并从结果页面中抓取数据点。

附:我正在使用 selenium Firefox 驱动程序从其他网站抓取数据,但该解决方案并不好,因为 selenium Firefox 驱动程序依赖于 FireFox 的 EXE,即必须在运行抓取程序之前安装 Firefox。

Selenium Firefox 驱动程序的一个实例消耗大约 100MB 内存,而我的要求是一次运行多个实例以使抓取过程更快,因此也存在内存限制。

Firefox 在执行 scraper 时有时会崩溃,不知道为什么。另外,我需要无窗口抓取,这在 Selenium Firefox 驱动程序中是不可能的。

我的最终目标是在 Heroku 上运行抓取工具,并且我在那里有 Linux 环境,因此 selenium Firefox 驱动程序无法在 Heroku 上运行。 谢谢


基本上,您有很多工具可供选择:

  • scrapy
  • 美丽汤
  • lxml
  • 机械化
  • requests (and 请求)
  • selenium
  • ghost.py

这些工具有不同的用途,但可以根据任务混合在一起。

Scrapy 是一个强大且非常智能的工具,用于爬行网站、提取数据。但是,当涉及到操作页面时:单击按钮、填写表单 - 它变得更加复杂:

  • 有时,通过直接在 scrapy 中进行底层表单操作,可以轻松模拟填写/提交表单
  • 有时,你必须使用其他工具来帮助 scrapy - 比如 mechanize 或 selenium

如果您的问题更加具体,将有助于了解您应该使用或选择哪种工具。

看一下有趣的 scrapy 和 selenium 组合的示例。这里,selenium 的任务是点击按钮并为 scrapy items 提供数据:

import time
from scrapy.item import Item, Field

from selenium import webdriver

from scrapy.spider import BaseSpider


class ElyseAvenueItem(Item):
    name = Field()


class ElyseAvenueSpider(BaseSpider):
    name = "elyse"
    allowed_domains = ["ehealthinsurance.com"]
    start_urls = [
    'http://www.ehealthinsurance.com/individual-family-health-insurance?action=changeCensus&census.zipCode=48341&census.primary.gender=MALE&census.requestEffectiveDate=06/01/2013&census.primary.month=12&census.primary.day=01&census.primary.year=1971']

    def __init__(self):
        self.driver = webdriver.Firefox()

    def parse(self, response):
        self.driver.get(response.url)
        el = self.driver.find_element_by_xpath("//input[contains(@class,'btn go-btn')]")
        if el:
            el.click()

        time.sleep(10)

        plans = self.driver.find_elements_by_class_name("plan-info")
        for plan in plans:
            item = ElyseAvenueItem()
            item['name'] = plan.find_element_by_class_name('primary').text
            yield item

        self.driver.close()

UPDATE:

这是一个关于如何在您的案例中使用 scrapy 的示例:

from scrapy.http import FormRequest
from scrapy.item import Item, Field
from scrapy.selector import HtmlXPathSelector

from scrapy.spider import BaseSpider


class AcrisItem(Item):
    borough = Field()
    block = Field()
    doc_type_name = Field()


class AcrisSpider(BaseSpider):
    name = "acris"
    allowed_domains = ["a836-acris.nyc.gov"]
    start_urls = ['http://a836-acris.nyc.gov/DS/DocumentSearch/DocumentType']


    def parse(self, response):
        hxs = HtmlXPathSelector(response)
        document_classes = hxs.select('//select[@name="combox_doc_doctype"]/option')

        form_token = hxs.select('//input[@name="__RequestVerificationToken"]/@value').extract()[0]
        for document_class in document_classes:
            if document_class:
                doc_type = document_class.select('.//@value').extract()[0]
                doc_type_name = document_class.select('.//text()').extract()[0]
                formdata = {'__RequestVerificationToken': form_token,
                            'hid_selectdate': '7',
                            'hid_doctype': doc_type,
                            'hid_doctype_name': doc_type_name,
                            'hid_max_rows': '10',
                            'hid_ISIntranet': 'N',
                            'hid_SearchType': 'DOCTYPE',
                            'hid_page': '1',
                            'hid_borough': '0',
                            'hid_borough_name': 'ALL BOROUGHS',
                            'hid_ReqID': '',
                            'hid_sort': '',
                            'hid_datefromm': '',
                            'hid_datefromd': '',
                            'hid_datefromy': '',
                            'hid_datetom': '',
                            'hid_datetod': '',
                            'hid_datetoy': '', }
                yield FormRequest(url="http://a836-acris.nyc.gov/DS/DocumentSearch/DocumentTypeResult",
                                  method="POST",
                                  formdata=formdata,
                                  callback=self.parse_page,
                                  meta={'doc_type_name': doc_type_name})

    def parse_page(self, response):
        hxs = HtmlXPathSelector(response)

        rows = hxs.select('//form[@name="DATA"]/table/tbody/tr[2]/td/table/tr')
        for row in rows:
            item = AcrisItem()
            borough = row.select('.//td[2]/div/font/text()').extract()
            block = row.select('.//td[3]/div/font/text()').extract()

            if borough and block:
                item['borough'] = borough[0]
                item['block'] = block[0]
                item['doc_type_name'] = response.meta['doc_type_name']

                yield item

保存在spider.py并通过运行scrapy runspider spider.py -o output.json and in output.json你会看见:

{"doc_type_name": "CONDEMNATION PROCEEDINGS ", "borough": "Borough", "block": "Block"}
{"doc_type_name": "CERTIFICATE OF REDUCTION ", "borough": "Borough", "block": "Block"}
{"doc_type_name": "COLLATERAL MORTGAGE ", "borough": "Borough", "block": "Block"}
{"doc_type_name": "CERTIFIED COPY OF WILL ", "borough": "Borough", "block": "Block"}
{"doc_type_name": "CONFIRMATORY DEED ", "borough": "Borough", "block": "Block"}
{"doc_type_name": "CERT NONATTCHMENT FED TAX LIEN ", "borough": "Borough", "block": "Block"}
...

希望有帮助。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Scrapy 抓取 Python 数据 的相关文章

  • 如何获取 Pandas df.merge() 不匹配的列名称

    给出以下数据 data df pd DataFrame Reference A A A B C C D E Value1 U U U V W W X Y Value2 u u u v w w x y index 1 2 3 4 5 6 7
  • 搜索/替换 xml 内容

    我已经成功地使用 xml etree ElementTree 解析 xml 搜索内容 然后将其写入不同的 xml 然而 我只是处理单个标签内的文本 import os sys glob xml etree ElementTree as ET
  • Django表单中的隐藏字段不在cleaned_data中

    我有这个表格 class CollaboratorForm forms Form user forms CharField label Username max length 100 canvas forms IntegerField wi
  • 如何在嵌套列表中查找给定元素?

    这是我的迭代解决方案 def exists key arg if not arg return False else for element in arg if isinstance element list for i in elemen
  • 获取父类名? [复制]

    这个问题在这里已经有答案了 class A object def get class self return self class class B A def init self A init self b B print b get cl
  • 使用 cx_oracle 返回 MERGE 中受影响的行数

    如何在 CX Oracle 中执行 MERGE INTO sql 命令来获取受影响的行数 当我在cx oracle 上执行MERGE SQL 时 我得到的cursor rowcount 为 1 有没有办法获取受合并影响的行数 由于 cx o
  • 并行执行按位运算的代码

    我有这段代码 通过将该 AU 矩阵的每个字节 8 个元素打包到 A 中来减少内存消耗 从而使 100k 200k 矩阵占用更少的空间 正如您所期望的 这段代码需要永远运行 我也计划将行数增加到 200k 我正在一个非常强大的实例 CPU 和
  • 如果每个元组中的第二项重复,如何从元组列表中删除元素?

    如果每个元组中的第二项重复 如何从元组列表中删除元素 例如 我有一个按第一个元素排序的列表 如下所示 alist 0 7897897 this is a foo bar sentence 0 653234 this is a foo bar
  • 为什么 scikit-learn SVM.SVC() 非常慢?

    我尝试使用SVM分类器来训练大约10万个样本的数据 但我发现它非常慢 甚至两个小时后也没有任何反应 当数据集有大约 1k 个样本时 我可以立即得到结果 我还尝试了 SGDClassifier 和朴素贝叶斯 速度相当快 几分钟内就得到了结果
  • python osmnx - 仅提取一个国家的大型高速公路

    我知道可以通过 OSMNX python 包提取城市的道路网络 详情请参阅https geoffboeing com 2016 11 osmnx python street networks https geoffboeing com 20
  • 如何向 Jupyter (ipython) 笔记本自动添加扩展?

    我已经安装了扩展 calico document tools 我可以使用以下命令从 Jupyter 笔记本中加载它 javascript IPython load extensions calico document tools 如何为每个
  • 如何在Python中将N毫秒添加到日期时间

    我正在设置一个日期时间变量 fulldate datetime datetime strptime date time Y m d H M S f 其中日期和时间是适合日期时间性质的字符串 如何将此日期时间增加 N 毫秒 Use timed
  • Python父类访问子私有变量

    以下代码会生成错误 class A object def say something self print self foo print self bar class B A def init self self foo hello sel
  • Python - 从一定范围内随机采样,同时避免某些值

    我一直在阅读有关random sample 函数在random模块 但没有看到任何可以解决我的问题的东西 我知道使用random sample range 1 100 5 会给我来自 人群 的 5 个独特样本 我想得到一个随机数range
  • Python httplib 和 POST

    我目前正在使用别人编写的一段代码 它用httplib向服务器发出请求 它以正确的格式提供所有数据 例如消息正文 标头值等 问题是 每次尝试发送 POST 请求时 数据都在那里 我可以在客户端看到它 但没有任何内容到达服务器 我已经阅读了库规
  • 抓取 Shopee API v4

    我有一个最终项目 其中我想要检索的数据是通过在shopee上抓取数据来获取的 但是当我在隐藏的API上抓取shopee时遇到问题 当我在Insomnia脚本上尝试时 脚本会运行 但是当我尝试时在本地或 google colab 脚本上 这是
  • 如何隐藏 Tkinter python Gui

    有人知道如何隐藏 python GUI Tkinter 我已经创建了键盘记录器 对于 GUI 我使用了 python 模块 Tkinter 我想添加名为 HIDE 的按钮 因此当用户单击它时 它将隐藏 GUI 当用户按下 CTRL E 之类
  • 如何限制单元测试的最大运行时间?

    我目前正在运行一些单元测试 这些测试可能需要很长时间才能失败或无限期地运行 在成功的测试运行中 它们总是会在一定的时间内完成 是否可以创建一个 pytest 单元测试 如果在一定时间内未完成 该测试就会失败 您可以安装 pytest tim
  • Mac 无法安装 Tensorflow

    我检查了我的 pip3 和 python3 版本 tensorflow MacBook Pro de Hector 2 tensorflow hectoresteban pip3 V pip 10 0 1 from Users hector
  • 获取 Flask 中没有端口的请求主机名

    我刚刚设法使用 Flask 获取我的应用程序服务器主机名request host and request url root 但这两个字段都返回请求主机名及其端口 我想使用仅返回请求主机名的字段 方法 而无需进行字符串替换 如果有 没有 We

随机推荐