【问题标题】:How can i use scrapy to parse links in JS?如何使用 scrapy 解析 JS 中的链接?
【发布时间】:2013-12-31 15:48:34
【问题描述】:

我正在尝试让 scrapy 解析页面上的链接以进行抓取。不幸的是,此页面上的链接包含在 JavaScript onclick 函数中。如果可能,我想使用 SgmlLinkExtractor 规则来提取链接以解析 JavaScript 并创建与 callback='parse_item' 一起使用的 URL。

这里是每个链接与 JS 函数的示例:

<a onclick="window.open('page.asp?ProductID=3679','productwin','width=700,height=475,scrollbars,resizable,status');" href="#internalpagelink">Link Text</a>

我只需要将链接提取器发送到回调 parse_item: http://domain.com/page.asp?ProductID=3679

我将如何编写 CrawlSpider 规则来做到这一点?

如果这是不可能的,那么最终能够解析在一组定义的起始页面上以这种 JavaScript 链接格式嵌入的所有页面的最佳方法是什么?

谢谢大家。

【问题讨论】:

  • 获取onclick属性,解析即可。
  • 是的,正如问题所说如何我将编写 CrawlSpider 规则来做到这一点?提取 onClick 函数的 page.asp?ProductID=3679 部分并将其作为 URL 返回的规则是什么样的?

标签: javascript python web-scraping scrapy


【解决方案1】:

可以使用SgmlLinkExtractorattrs参数。

  • attrs (list) – 查找要提取的链接时应考虑的属性列表(仅适用于 tags 参数中指定的那些标签)。默认为 ('href',)

和来自BaseSgmlLinkExtractorprocess_value参数:

  • process_value(可调用)– 一个函数,它接收从扫描的标签和属性中提取的每个值,并且可以修改该值并返回一个新值,或者返回 None 以完全忽略链接。如果未给出,则 process_value 默认为 lambda x: x。

因此,您将为“onclick”属性的值编写一个解析函数:

def process_onclick(value):
    m = re.search("window.open\('(.+?)'", value)
    if m:
        return m.group(1)

让我们检查一下这个正则表达式:

>>> re.search("window.open\('(.+?)'",
...           "window.open('page.asp?ProductID=3679','productwin','width=700,height=475,scrollbars,resizable,status');"
...          ).group(1)
'page.asp?ProductID=3679'
>>> 

然后在RuleSgmlLinkExtractor 中使用它

rules=(
    Rule(SgmlLinkExtractor(allow=(),
                           attrs=('onclick',),
                           process_value=process_onclick),
         callback='parse_item'),
)

【讨论】:

  • 谢谢保罗!看起来正是我所追求的。我从来不知道你可以使用和定义这样的规则。太棒了!
  • 对于其他人来说也只是上面的拼写错误。它应该是 attrs="onclick" 而不是 attr="onclick"
  • 好发现!谢谢@JnFity。我会修复答案
【解决方案2】:

这里可能BaseSpiderCrawlSpider 更合适。

您可以提取要抓取的链接并将其封装在 Request 对象中,然后发出此 Request object,如下所示:

def parse_xxx(self, response):
    """do some work"""
    req_objs = []
    req_objs.append(Request(SOME_URL, SOME_ARGS))
    """Add more `Request` objects"""
    for req in req_objs:
        yield req

【讨论】:

    猜你喜欢
    • 2019-09-18
    • 2021-03-22
    • 2019-07-05
    • 1970-01-01
    • 2016-02-12
    • 1970-01-01
    • 2020-01-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多