首页 文章

Scrapy Python spider无法使用LinkExtractor或手动Request()查找链接

提问于
浏览
1

我正在尝试编写一个Scrapy蜘蛛,它爬过域中的所有结果页面:https://www.ghcjobs.apply2jobs.com... . 代码应该做三件事:

(1)通过所有页面1-1000爬网 . 这些页面是相同的,除了区分URL的最后部分:&CurrentPage =# .

(2)跟踪结果表中包含职位发布的每个链接,其中链接的class = SearchResult . 这些是表中唯一的链接,所以我在这里没有任何麻烦 .

(3)以key:value JSON格式存储作业描述页面上显示的信息 . (这部分以初步的方式起作用)

之前我使用过scrapy和CrawlSpiders,使用'rule = [规则(Link ='= let ='方法递归解析页面以查找匹配给定正则表达式模式的所有链接 . 我目前难倒第1步,爬过一千个结果页面 .

下面是我的蜘蛛代码:

from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.http.request import Request
from scrapy.contrib.linkextractors import LinkExtractor
from genesisSpider.items import GenesisJob

class genesis_crawl_spider(CrawlSpider):
    name = "genesis"
    #allowed_domains = ['http://www.ghcjobs.apply2jobs.com']
    start_urls = ['https://www.ghcjobs.apply2jobs.com/ProfExt/index.cfm?fuseaction=mExternal.returnToResults&CurrentPage=1']

    #allow &CurrentPage= up to 1000, currently ~ 512
    rules = [Rule(LinkExtractor(allow=("^https://www.ghcjobs.apply2jobs.com/ProfExt/
index.cfm\?fuseaction=mExternal.returnToResults&CurrentPage=[1-1000]$")), 'parse_inner_page')]

def parse_inner_page(self, response):
    self.log('===========Entrered Inner Page============')
    self.log(response.url)
    item = GenesisJob()
    item['url'] = response.url

    yield item

这是蜘蛛的输出,顶部有一些执行代码:

2014-09-02 16:02:48-0400 [genesis] DEBUG: Crawled (200) <GET https://www.ghcjobs
.apply2jobs.com/ProfExt/index.cfm?fuseaction=mExternal.returnToResults&CurrentPa
ge=1> (referer: None) ['partial']
2014-09-02 16:02:48-0400 [genesis] DEBUG: Crawled (200) <GET https://www.ghcjobs
.apply2jobs.com/ProfExt/index.cfm?CurrentPage=1&fuseaction=mExternal.returnToRes
ults> (referer: https://www.ghcjobs.apply2jobs.com/ProfExt/index.cfm?fuseaction=
mExternal.returnToResults&CurrentPage=1) ['partial']
2014-09-02 16:02:48-0400 [genesis] DEBUG: ===========Entrered Inner Page========
====
2014-09-02 16:02:48-0400 [genesis] DEBUG: https://www.ghcjobs.apply2jobs.com/Pro
fExt/index.cfm?CurrentPage=1&fuseaction=mExternal.returnToResults
2014-09-02 16:02:48-0400 [genesis] DEBUG: Scraped from <200 https://www.ghcjobs.
apply2jobs.com/ProfExt/index.cfm?CurrentPage=1&fuseaction=mExternal.returnToResu
lts>
        {'url': 'https://www.ghcjobs.apply2jobs.com/ProfExt/index.cfm?CurrentPag
e=1&fuseaction=mExternal.returnToResults'}
2014-09-02 16:02:48-0400 [genesis] INFO: Closing spider (finished)
2014-09-02 16:02:48-0400 [genesis] INFO: Dumping Scrapy stats:
        {'downloader/request_bytes': 930,
         'downloader/request_count': 2,
         'downloader/request_method_count/GET': 2,
         'downloader/response_bytes': 92680,
         'downloader/response_count': 2,
         'downloader/response_status_count/200': 2,
         'finish_reason': 'finished',
         'finish_time': datetime.datetime(2014, 9, 2, 20, 2, 48, 611000),
         'item_scraped_count': 1,
         'log_count/DEBUG': 7,
         'log_count/INFO': 7,
         'request_depth_max': 1,
         'response_received_count': 2,
         'scheduler/dequeued': 2,
         'scheduler/dequeued/memory': 2,
         'scheduler/enqueued': 2,
         'scheduler/enqueued/memory': 2,
         'start_time': datetime.datetime(2014, 9, 2, 20, 2, 48, 67000)}
2014-09-02 16:02:48-0400 [genesis] INFO: Spider closed (finished)

目前,我坚持这个项目的目标(1) . 如您所见,我的蜘蛛只会爬过start_url页面 . 正如我测试正则表达式一样,我的正则表达式应该正确定位页面导航按钮 . 我的回调函数parse_inner_page正在工作,如我插入的调试注释所示,但仅在第一页上显示 . 我是否正确使用“规则”?我当时认为可能是HTTPS的页面有点怪......

Jut作为修补解决方案的一种方法,我尝试使用第二页结果的手动请求;这没用 . 这也是代码 .

Request("https://www.ghcjobs.apply2jobs.com/ProfExt/index.cfm?fuseaction=mExternal.returnToResults&CurrentPage=2",  callback = 'parse_inner_page')

有人可以提供任何指导吗?有没有更好的方法来做到这一点?自上周五以来,我一直在研究SO / Scrapy文档 . 非常感谢 .

更新:我已经解决了这个问题 . 问题在于我使用的启动URL .

start_urls = ['https://www.ghcjobs.apply2jobs.com/ProfExt/index.cfm?fuseaction=mExternal.returnToResults&CurrentPage=1']

导致在This页面上单击"search"按钮导致的表单提交后页面 . 这在客户端运行javascript以向服务器提交表单,该服务器报告完整的作业板,第1-512页 . 但是,存在另一个硬编码的URL,显然无需使用任何客户端javascript即可调用服务器 . 所以现在我的开始网址是

start_urls = ['https://www.ghcjobs.apply2jobs.com/ProfExt/index.cfm?fuseaction=mExternal.searchJobs']

一切都恢复正常!将来,请检查是否存在用于调用服务器资源的任何javascript独立URL .

1 回答

  • 2

    您确定Scrapy以与您相同的方式查看网页吗?如今,越来越多的网站是由Javascript,Ajax构建的 . 而那些动态内容可能需要一个功能齐全的浏览器才能完全填充 . 但是,Nutch和Scrapy都无法处理开箱即用的问题 .

    首先,您需要确保通过scrapy检索您感兴趣的Web内容 . 有几种方法可以做到这一点 . 我通常使用 urllib2beautifulsoup4 来快速尝试 . 您的起始页面未通过我的测试 .

    $ python
    Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
    [GCC 4.8.2] on linux2
    Type "help", "copyright", "credits" or "license" for more information.
    >>> import urllib2
    >>> from bs4 import BeautifulSoup
    >>> url = "https://www.ghcjobs.apply2jobs.com/ProfExt/index.cfm?fuseaction=mExternal.returnToResults&CurrentPage=1"
    
    >>> html = urllib2.urlopen(url).read()
    >>> soup = BeautifulSoup(html)
    >>> table = soup.find('div', {'id':'VESearchResults'})
    >>> table.text
    u'\n\n\n\r\n\t\t\tJob Title\xa0\r\n\t\t\t\r\n\t\t\n\r\n\t\t\tArea of Interest\xa0\r\n\t\t\t\r\n\t\t\n\r\n\t\t\tLocation\xa0\r\n\t\t\t\r\n\t\t\n\r\n\t\t\tState\xa0\r\n\t\t\t\r\n\t\t\n\r\n\t\t\tCity\xa0\r\n\t\t\t\r\n\t\t\n\n\n\r\n\t\t\t\t\tNo results matching your criteria.\r\n\t\t\t\t\n\n\n'
    >>>
    

    如您所见,“没有符合您条件的结果!”我想你可能需要弄清楚为什么没有填充内容 . Cookies ?邮寄而不是获取?用户代理..等 .

    此外,您可以使用scrapy parse命令来帮助您进行调试 . 例如,我经常使用此命令 .

    scrapy parse http://example.com --rules
    

    其他一些scrapy commands,也许Selenium可能会有所帮助 .

    在这里我使用在iPython中运行scrapy shell来检查你的起始URL以及我在浏览器中可以看到的第一条包含Englewood的记录,它在sctml抓取的html中不存在

    Here I am using running scrapy shell in iPython to inspect your start url and also the first record that I can see in my browser contains Englewood and it doesn't exist in the html that scrapy grabbed.

    更新:

    你正在做的是一个非常微不足道的刮擦工作,你真的不需要Scrapy,它有点矫枉过正 . 以下是我的建议:

    • 看看Selenium(我假设你正在编写Python)并在尝试在服务器上运行时最终制作无头Selenium .

    • 您可以使用PhantomJS实现这一点,PhantomJS是一个更轻松的Javascript执行程序,可以完成您的工作 . Here是另一个可能有用的stackoverflow问题 .

    • 几个你可以从事职业生涯的资源 .

相关问题