标签: scrapy

提交使用 Scrapy 动态呈现的表单?

我正在尝试使用 Scrapy 提交动态生成的用户登录表单,然后解析页面上与成功登录相对应的 HTML。

我想知道如何使用 Scrapy 或 Scrapy 和 Selenium 的组合来做到这一点。Selenium 使得在 DOM 上找到元素成为可能,但我想知道是否有可能在获得完整的 HTML 后将控制权“交还”给 Scrapy,以允许它执行表单提交并保存必要的 cookie ,会话数据等以抓取页面。

基本上,我认为 Selenium 是必要的唯一原因是因为我需要在 Scrapy 查找<form>元素之前从 Javascript 呈现页面。但是,有没有其他替代方法?

谢谢!

编辑:这个问题类似于这一个,但不幸的请求库而不是硒或Scrapy接受的答案交易。尽管在某些情况下可能出现这种情况(观看此内容以了解更多信息),但正如 alecxe 指出的那样,如果“页面的某些部分 [例如表单] 通过 API 调用加载并在帮助下插入到页面中,则可能需要 Selenium在浏览器中执行的 javascript 代码”。

python selenium scrapy selenium-webdriver scrapy-spider

1
推荐指数
1
解决办法
1436
查看次数

循环中的 Scrapy 调用请求

我想废弃一个包含带有过滤选项的组合框的网页。基本 url 相同,但请求有效负载取决于选定的组合框值。我有一个可用选项列表,我创建了一个循环,它遍历组合框值并执行请求。代码如下:

def parse_product_lines(self, response):
    options = json.loads(response.body_as_unicode())
    product_lines = options['products']

    for product_line in product_lines:
        payload = self.prepare_payload(product_line)

        scrapy.Request('http://example.com',
                       method="POST",
                       body=urllib.urlencode(payload),
                       callback=self.parse_items)

def parse_items(self, response):
    print response
Run Code Online (Sandbox Code Playgroud)

,但不执行请求。有人知道那里发生了什么吗?

python web-crawler request scrapy

1
推荐指数
1
解决办法
2525
查看次数

Scrapy刮板速度慢的原因

我创建了一个非常慢的新 Scrapy 蜘蛛。它每秒只能抓取大约两页,而我创建的其他 Scrapy 爬虫的抓取速度要快得多。

我想知道是什么导致了这个问题,以及如何解决这个问题。该代码与其他蜘蛛并没有太大不同,我不确定它是否与问题有关,但如果您认为可能涉及到它,我会添加它。

事实上,我的印象是请求不是异步的。我从来没有遇到过这种问题,而且我对 Scrapy 还是很陌生。

编辑

这是蜘蛛:

class DatamineSpider(scrapy.Spider):
    name = "Datamine"
    allowed_domains = ["domain.com"]
    start_urls = (
        'http://www.example.com/en/search/results/smth/smth/r101/m2108m',
    )

    def parse(self, response):
        for href in response.css('.searchListing_details .search_listing_title .searchListing_title a::attr("href")'):
            url = response.urljoin(href.extract())
            yield scrapy.Request(url, callback=self.parse_stuff)
        next_page = response.css('.pagination .next a::attr("href")')
        next_url = response.urljoin(next_page.extract()[0])
        yield scrapy.Request(next_url, callback=self.parse)

    def parse_stuff(self, response):
        item = Item()
        item['value'] = float(response.xpath('//*[text()="Price" and not(@class)]/../../div[2]/span/text()').extract()[0].split(' ')[1].replace(',',''))
        item['size'] =  float(response.xpath('//*[text()="Area" and not(@class)]/../../div[2]/text()').extract()[0].split(' ')[0].replace(',', '.'))
        try:
            item['yep'] = float(response.xpath('//*[text()="yep" and not(@class)]/../../div[2]/text()').extract()[0])
        except IndexError:
            print …
Run Code Online (Sandbox Code Playgroud)

python web-crawler scrapy web-scraping scrapy-spider

1
推荐指数
1
解决办法
4402
查看次数

Scrapy 将子站点项与站点项合并

我试图从子站点中抓取详细信息并与通过 site 抓取的详细信息合并。我一直在研究 stackoverflow 以及文档。但是,我仍然无法让我的代码工作。似乎我从子站点提取其他详细信息的功能不起作用。如果有人能看一下,我将不胜感激。

# -*- coding: utf-8 -*-
from scrapy.spiders import Spider
from scrapy.selector import Selector
from scrapeInfo.items import infoItem
import pyodbc


class scrapeInfo(Spider):
    name = "info"
    allowed_domains = ["http://www.nevermind.com"]
    start_urls = []

    def start_requests(self):

        #Get infoID and Type from database
        self.conn = pyodbc.connect('DRIVER={SQL Server};SERVER=server;DATABASE=dbname;UID=user;PWD=password')
        self.cursor = self.conn.cursor()
        self.cursor.execute("SELECT InfoID, category FROM dbo.StageItem")

        rows = self.cursor.fetchall()

        for row in rows:
            url = 'http://www.nevermind.com/info/'
            InfoID = row[0]
            category = row[1]
            yield self.make_requests_from_url(url+InfoID, InfoID, category, self.parse)

    def make_requests_from_url(self, …
Run Code Online (Sandbox Code Playgroud)

python merge function scrapy

1
推荐指数
1
解决办法
1338
查看次数

Scrapy - 使用多个选项发送表单数据

我正在使用scrapy来解析具有以下形式的网站:

<form id="form1"...>
    <select name="codes" multiple="multiple"...>
        <option value="0">Option one</option>
        <option value="1">Option two</option>
        <option value="2">Option three</option>
        ....
    </select>
</form>
Run Code Online (Sandbox Code Playgroud)

我正在填写并使用以下代码提交表单:

submit_form = FormRequest.from_response(response,
                                        formxpath="//form[@id='form1']",
                                        formdata={'codes': '0'},
                                        callback=self.parse_table)
yield submit_form
Run Code Online (Sandbox Code Playgroud)

如何在表单数据中提交多个代码?我试过了:

formdata={'codes': '["0", "1", "2"]'},
formdata={'codes': ['0', '1', '2']},
Run Code Online (Sandbox Code Playgroud)

没有任何运气。

编辑:

表单有额外的输入控件,其中一些是隐藏的,它们在表单中正确传递。我在表单提交后看到的就像服务器返回到与表单相同的页面,当我期待一个新页面的表格实际上包含我想要检索的数据时。

我对服务器后端知之甚少,只知道它是用 .NET 2.0 构建的。这是一个非常古老的网站,来自政府的依赖。

谢谢。

python forms scrapy

1
推荐指数
1
解决办法
875
查看次数

如何设置将scrapy作为python脚本运行的默认设置?

我想将scrapy作为python脚本运行,但我不知道如何正确设置设置或如何提供它们。我不确定这是否是设置问题,但我认为是。

我的配置:

  • Python 2.7 x86(作为虚拟环境)
  • Scrapy 1.2.1
  • 赢 7 x64

我接受了https://doc.scrapy.org/en/latest/topics/practices.html#run-scrapy-from-a-script的建议来让它运行。我对以下建议有一些问题:

如果您在 Scrapy 项目中,则可以使用一些额外的帮助程序将这些组件导入项目中。您可以自动导入将其名称传递给 CrawlerProcess 的蜘蛛,并使用 get_project_settings 获取带有项目设置的 Settings 实例。

那么“在 Scrapy 项目中”是什么意思?当然,我必须导入库并安装依赖项,但我想避免使用scrapy crawl xyz.

这是 myScrapy.py 的代码

from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settings
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from scrapy.item import Item, Field
import os, argparse


#Initialization of directories
projectDir = os.path.dirname(os.path.realpath('__file__'))
generalOutputDir = os.path.join(projectDir, 'output')

parser = argparse.ArgumentParser()
parser.add_argument("url", help="The url which you want to scan", type=str)
args …
Run Code Online (Sandbox Code Playgroud)

python scrapy python-2.7 scrapy-spider

1
推荐指数
1
解决办法
1801
查看次数

在scrapy中来自_crawler的类方法

在问了我的最后一个问题(如何将参数传递给scrapy管道对象)之后,我试图更好地理解scrapy中管道和爬虫之间的关系

答案之一是:

@classmethod
def from_crawler(cls, crawler):
    # Here, you get whatever value was passed through the "table" parameter
    settings = crawler.settings
    table = settings.get('table')

    # Instantiate the pipeline with your table
    return cls(table)

def __init__(self, table):
    _engine = create_engine("sqlite:///data.db")
    _connection = _engine.connect()
    _metadata = MetaData()
    _stack_items = Table(table, _metadata,
                         Column("id", Integer, primary_key=True),
                         Column("detail_url", Text),
    _metadata.create_all(_engine)
    self.connection = _connection
    self.stack_items = _stack_items
Run Code Online (Sandbox Code Playgroud)

我很困惑:

@classmethod
def from_crawler(cls, crawler):
    # Here, you get whatever value was passed through the "table" parameter …
Run Code Online (Sandbox Code Playgroud)

python scrapy

1
推荐指数
1
解决办法
1159
查看次数

scrapy shell:将结果输出到文件

我怎样才能在scrapy shell中输出结果到一个文件,最好是csv?

我的bpython外壳中有一个有趣的元素列表,我可以制作item它们。但是如何将其重定向到文件?

python csv scrapy output

1
推荐指数
1
解决办法
1908
查看次数

Scrapy POST 请求不起作用 - 400 Bad Request

我正在从 python 的requests库转移到scrapy,并且在发出简单的 POST 请求时遇到问题。我正在设置标题和有效负载:

headers = {
    'Accept':'*/*',
    'Accept-Encoding':'gzip, deflate, br',
    'accept-language':'en_US',
    'Connection':'keep-alive',
    'Content-Length':'151',
    'content-type':'application/json',
    'Cookie':cookie,
    'Host':host,
    'Origin':origin,
    'Referer':referer,
    'User-Agent':'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36',
    'x-csrf-token':token
}

payload = {"targetLocation":{"latitude":lat,"longitude":lng}}
Run Code Online (Sandbox Code Playgroud)

然后像这样提出请求:

def start_requests(self):
    u = self.url
    yield scrapy.Request(u, method='POST',
                            callback=self.parse_httpbin,
                            errback=self.errback_httpbin,
                            body=json.dumps(self.payload),
                            headers=self.headers)
Run Code Online (Sandbox Code Playgroud)

这一直给我 400 状态。如果我使用与requests库完全相同的标头和有效负载发出请求,它会按预期为我提供 200 状态并返回一个 json。

r = requests.post(url, headers=headers, data=json.dumps(payload), verify=False)
Run Code Online (Sandbox Code Playgroud)

我究竟做错了什么?

python scrapy http-status-code-400 python-requests

1
推荐指数
1
解决办法
2752
查看次数

Scrapy CrawlSpider 基于 start_urls 的动态规则?

我正在编写一个 Scrapy 抓取器,它使用 CrawlSpider 来抓取站点,查看其内部链接,并抓取任何外部链接(域与原始域不同的域的链接)的内容。

我设法用 2 条规则做到了这一点,但它们基于被抓取的站点的域。如果我想在多个网站上运行它,我会遇到一个问题,因为我不知道我目前在哪个“start_url”上,所以我无法适当地更改规则。

到目前为止,这是我想到的,它适用于一个网站,但我不确定如何将其应用于网站列表:

class HomepagesSpider(CrawlSpider):
    name = 'homepages'

    homepage = 'http://www.somesite.com'

    start_urls = [homepage]

    # strip http and www
    domain = homepage.replace('http://', '').replace('https://', '').replace('www.', '')
    domain = domain[:-1] if domain[-1] == '/' else domain

    rules = (
        Rule(LinkExtractor(allow_domains=(domain), deny_domains=()), callback='parse_internal', follow=True),
        Rule(LinkExtractor(allow_domains=(), deny_domains=(domain)), callback='parse_external', follow=False),
    )

    def parse_internal(self, response):

        # log internal page...

    def parse_external(self, response):

        # parse external page...
Run Code Online (Sandbox Code Playgroud)

这可能可以通过在调用刮刀时将 start_url 作为参数传递来完成,但我正在寻找一种在刮刀本身内以编程方式执行此操作的方法。

有任何想法吗?谢谢!

西蒙。

python web-crawler scrapy web-scraping scrapy-spider

1
推荐指数
1
解决办法
1485
查看次数