Scrapy蜘蛛无法找到加载点击的网址

时间:2017-03-24 01:15:32

标签: python web-scraping scrapy scrapy-spider

我试图从此页面抓取数据 - http://catalog.umassd.edu/content.php?catoid=45&navoid=3554

我希望通过本部门的“展示”课程扩展每个部分'链接,然后获取该页面上每门课程的课程信息(文本)。

我写了以下脚本:

 from scrapy.spiders import CrawlSpider, Rule, BaseSpider, Spider
 from scrapy.linkextractors.lxmlhtml import LxmlLinkExtractor 
 from scrapy.selector import Selector
 from scrapy.http import HtmlResponse

 from courses.items import Course


class EduSpider(CrawlSpider):
    name = 'umassd.edu'
    allowed_domains = ['umassd.edu']
    start_urls = ['http://catalog.umassd.edu/content.php']

    rules = (Rule(LxmlLinkExtractor(
         allow=('.*/http://catalog.umassd.edu/preview_course.php?
         catoid=[0-9][0-9]&coid=[0-9][0-9][0-9][0-9][0-9][0-9]', ),
         ), callback='parse_item'),

    def parse_item(self, response):
        item = Course()
        print (response)

现在,无论我给出什么start_url,蜘蛛似乎都无法到达preview_course.php链接 - 我尝试了一些变化。 脚本退出时根本不抓取任何/content.php页面。

这仅用于教育目的。

1 个答案:

答案 0 :(得分:3)

您要查找的网址是通过AJAX请求检索的。如果您打开浏览器开发工具并转到“网络”选项卡,则会在单击按钮时看到正在发出的请求,如下所示:

http://catalog.umassd.edu/ajax/preview_filter_show_hide_data.php?show_hide=show&cat_oid=45&nav_oid=3554&ent_oid=2027&type=c&link_text=this%20department

此网址由javascript生成,然后下载内容并将其注入您的网页 由于scrapy不执行任何javascript,您需要自己重新创建此URL。幸运的是,在您的情况下对此进行逆向工程非常容易。

如果您检查html源代码,您可以看到“此部门的显示课程”链接节点上有一些有趣的内容:

<a href="#" 
target="_blank" 
onclick="showHideFilterData(this, 'show', '45', '3554', '2027', 'c', 'this department'); return false;>
Display courses for this department.</a>

我们可以看到,当我们点击一​​些javascript函数时,如果我们将它与上面的url进行比较,你可以清楚地看到一些相似之处。

现在我们可以使用以下数据重新创建此网址:

class MySpider(scrapy.Spider):
    name = 'myspider'
    start_urls = ['http://catalog.umassd.edu/content.php?catoid=45&navoid=3554']

    def parse(self, response):
        # get "onclick" java function of every "show more" link
        # and extract parameters supplied to this function with regular expressions
        links = response.xpath("//a/@onclick[contains(.,'showHide')]")
        for link in links:
            args = link.re("'(.+?)'")
            # make our url by putting arguments from page source 
            # into a template of an url
            url = 'http://catalog.umassd.edu/ajax/preview_filter_show_hide_data.php?show_hide={}&cat_oid={}&nav_oid={}&ent_oid={}&type={}&link_text={}'.format(*args)
            yield scrapy.Request(url, self.parse_more) 

    def parse_more(self, response):
        # here you'll get page source with all of the links