[英]Scrapy Python spider unable to find links using LinkExtractor or by manual Request()
我正在尝试编写一个Scrapy蜘蛛,该蜘蛛会爬过该域上的所有结果页面: https://www.ghcjobs.apply2jobs.com...。 该代码应该做三件事:
(1)搜寻所有1-1000页。 这些页面是相同的,只是URL的最后部分与众不同:&CurrentPage =#。
(2)在结果表中包含作业发布的每个链接之后,其中链接的类= SearchResult。 这些是表中的唯一链接,因此我在这里没有任何麻烦。
(3)将工作描述页面上显示的信息以key:value JSON格式存储。 (这部分工作很简单)
之前,我曾使用scrapy和CrawlSpiders,使用“ rule = [Rule(LinkExtractor(allow =)”方法来递归地解析页面,以查找与给定正则表达式模式匹配的所有链接。目前,我陷入了第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
这是Spider的输出,上面的一些执行代码被截断了:
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)。 如您所见,我的Spider仅在start_url页面中进行爬网。 我已经测试过正则表达式,因此我的正则表达式应该正确定位页面导航按钮。 我的回调函数parse_inner_page正在运行,正如我插入的调试注释所示,但仅在第一页上。 我是否错误地使用了“规则”? 我当时以为是HTTPS网页导致了某种原因?
作为解决方案的一种方式,我尝试对第二页结果使用手动请求。 这没有用。 这也是该代码。
Request("https://www.ghcjobs.apply2jobs.com/ProfExt/index.cfm?fuseaction=mExternal.returnToResults&CurrentPage=2", callback = 'parse_inner_page')
谁能提供任何指导? 有没有更好的方法可以做到这一点? 从周五开始,我一直在SO / Scrapy文档中对此进行研究。 非常感谢。
更新:我已经解决了这个问题。 问题出在我使用的起始网址。
start_urls = ['https://www.ghcjobs.apply2jobs.com/ProfExt/index.cfm?fuseaction=mExternal.returnToResults&CurrentPage=1']
指向表单提交后的页面,该页面是单击此页面上的“搜索”按钮而得到的。 这将在客户端运行javascript以向服务器提交表单,该表单将报告完整的工作板,第1-512页。 但是,存在另一个硬编码的URL,该URL显然可以调用服务器,而无需使用任何客户端javascript。 所以现在我的起始网址是
start_urls = ['https://www.ghcjobs.apply2jobs.com/ProfExt/index.cfm?fuseaction=mExternal.searchJobs']
一切都回到正轨! 将来,请检查是否存在用于调用服务器资源的任何独立于JavaScript的URL。
您确定Scrapy与您看到网页的方式相同吗? 如今,越来越多的网站是由Javascript,Ajax建立的。这些动态内容可能需要功能齐全的浏览器才能完全填充。 但是,无论是Nutch还是Scrapy都不会开箱即用。
首先,您需要确保您感兴趣的Web内容可以通过scrapy检索。 有几种方法可以做到这一点。 我通常使用urllib2
和beautifulsoup4
快速尝试一下。 您的起始页未通过我的测试。
$ 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'
>>>
如您所见,“没有符合您条件的结果!” 我认为您可能需要弄清楚为什么未填充内容。 饼干? 发布而不是获取? 用户代理等
另外,您可以使用scrapy parse命令来帮助您调试。 例如,我经常使用此命令。
scrapy parse http://example.com --rules
其他一些易用的命令 ,也许是Selenium,可能会在以后帮助您。
在这里,我使用的是在iPython中运行scrapy shell来检查您的起始URL,以及我在浏览器中看到的第一条记录包含Englewood,并且在scrapy抓取的html中不存在
更新:
您正在做的是一件非常琐碎的刮削工作,并且您确实不需要Scrapy,这有点过头了。 这是我的建议:
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.