当执行第一个产量时,它不会进入函数 parse_url ,并且在执行第二个 yield 时,它将不会返回该函数解析,它就结束了。在整个过程中,没有例外。我不知道如何处理这个问题,我需要帮助。
import scrapy
import re
from crawlurl.items import CrawlurlItem
class HouseurlSpider(scrapy.Spider):
name = 'houseurl'
allowed_domains = ['qhd.58.com/ershoufang/']
start_urls = ['http://qhd.58.com/ershoufang//']
header = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0'
}
def parse(self, response):
urls = response.xpath('//div[@class="list-info"]/h2[@class="title"]/a/@href').extract()
next_url = response.xpath('//a[@class="next"]/@href').extract()
for url in urls:
yield scrapy.Request(url,headers=self.header,callback=self.parse_url)
if next_url:
next_url = next_url[0]
yield scrapy.Request(next_url,headers=self.header,callback=self.parse)
def parse_url(self,response):
item = CrawlurlItem()
url_obj = re.search('(http://qhd.58.com/ershoufang/\d+x.shtml).*',response.url)
url = url_obj.group(1)
item['url'] = url
yield item
答案 0 :(得分:2)
如果您仔细查看了日志,那么您可能已经注意到scrapy
过滤了异地域请求。这意味着当scrapy
尝试ping short.58.com
和jxjump.58.com
时,它没有完成。您可以将这些域添加到Spider类中的allowed_domains
过滤器,您将看到正在发送的请求。
替换:
allowed_domains = ['qhd.58.com/ershoufang/']
使用:
allowed_domains = ['qhd.58.com', 'short.58.com', 'jxjump.58.com']
它应该有效!
答案 1 :(得分:0)
问题出在你的allowed_domains
条款中。它应该只包含域,没有路径。因此,您的qhd.58.com/ershoufang/
项目无法识别。因此,您产生的所有网址(start_urls
除外)实际上已被过滤掉,这反映在日志中:
2017-06-24 14:05:09 [scrapy.spidermiddlewares.offsite] DEBUG: Filtered offsite request to 'qhd.58.com': <GET http://qhd.58.com/ershoufang/30456249766826x.shtml>
这绝对不是你想要的。您可以通过在allowed_domains
中放置一个域并在其他位置过滤不需要的URL来解决此问题,例如:在yield
之前:
allowed_domains = ['qhd.58.com']
...
for url in urls:
if 'qhd.58.com/ershoufang/' in url:
yield response.follow(url, self.parse_url, headers=self.header)
...
通常最好使用response.follow()
代替scrapy.Request()
,因为前者支持相对网址。