如何使用 scrapy 抓取一个网站,该网站在下一个按钮中隐藏了 url 作为 href="javascript:;"
How to use scrapy to crawl a website which hides the url as href="javascript:;" in the next button
我最近在学习 python 和 scrapy。我用谷歌搜索了几天,但我似乎没有找到任何关于如何在具有隐藏 url 的网站上抓取多个页面的说明 - <a href="javascript:;"
。基本上每个页面包含20个列表,每次点击“>>”按钮,它会加载接下来的20个项目。我不知道如何找到实际的网址,下面是供您参考的源代码。非常感谢任何指点和帮助。
使用 Web 浏览器访问站点并激活 Web 开发人员工具(以下屏幕截图是使用 Firefox 和附加组件 Firebug 制作的)您应该能够分析网络请求和响应。它将向您显示站点分页按钮发送如下请求:
所以 URL 似乎是:
http://rent.591.com.hk/?m=home&c=search&a=rslist&type=1&shType=list&p=2&searchtype=1
但这不是一个正常的请求。这是一个XMLHttpRequest
。在 Header
选项卡下显示。响应在 JSON:
所以你不需要从复杂的嵌套html结构中获取数据,而是可以直接从JSON字典中获取。
我最终得到了这个草率的代码(还有改进的余地):
import scrapy
import json
class RentObject(scrapy.Item):
address = scrapy.Field()
purpose = scrapy.Field()
# Add more fields as needed
class ScrapeSpider(scrapy.Spider):
name = "rent_hk"
allowed_domains = ['591.com.hk']
start_urls = ['http://rent.591.com.hk/?hl=en-us#list' ]
page_number = 0
page_num_max = 5 # for test purposes grab only up to 5 pages
def parse(self, response):
if 'page_number' in response.meta:
result_dict = json.loads(response.body) # get data as dict
for object in result_dict['items']:
ro = RentObject()
ro['address'] = object['address']
ro['purpose'] = object['purpose']
yield ro
# Make request for (next page) JSON data
self.page_number += 1
payload = {
'm': 'home',
'c': 'search',
'a': 'rslist',
'type': '1',
'p': str(self.page_number),
'searchtype': '1'
}
if self.page_number < self.page_num_max:
request = scrapy.FormRequest(url='http://rent.591.com.hk/',
method='GET',
formdata=payload,
headers={'Referer': 'http://rent.591.com.hk/?hl=en-us',
'X-Requested-With': 'XMLHttpRequest'},
callback=self.parse)
request.meta['page_number'] = self.page_number
yield request
这个网站对于一个 scrapy 初学者来说真的不容易 - 所以我整理了这个详细的答案。
我最近在学习 python 和 scrapy。我用谷歌搜索了几天,但我似乎没有找到任何关于如何在具有隐藏 url 的网站上抓取多个页面的说明 - <a href="javascript:;"
。基本上每个页面包含20个列表,每次点击“>>”按钮,它会加载接下来的20个项目。我不知道如何找到实际的网址,下面是供您参考的源代码。非常感谢任何指点和帮助。
使用 Web 浏览器访问站点并激活 Web 开发人员工具(以下屏幕截图是使用 Firefox 和附加组件 Firebug 制作的)您应该能够分析网络请求和响应。它将向您显示站点分页按钮发送如下请求:
所以 URL 似乎是:
http://rent.591.com.hk/?m=home&c=search&a=rslist&type=1&shType=list&p=2&searchtype=1
但这不是一个正常的请求。这是一个XMLHttpRequest
。在 Header
选项卡下显示。响应在 JSON:
所以你不需要从复杂的嵌套html结构中获取数据,而是可以直接从JSON字典中获取。
我最终得到了这个草率的代码(还有改进的余地):
import scrapy
import json
class RentObject(scrapy.Item):
address = scrapy.Field()
purpose = scrapy.Field()
# Add more fields as needed
class ScrapeSpider(scrapy.Spider):
name = "rent_hk"
allowed_domains = ['591.com.hk']
start_urls = ['http://rent.591.com.hk/?hl=en-us#list' ]
page_number = 0
page_num_max = 5 # for test purposes grab only up to 5 pages
def parse(self, response):
if 'page_number' in response.meta:
result_dict = json.loads(response.body) # get data as dict
for object in result_dict['items']:
ro = RentObject()
ro['address'] = object['address']
ro['purpose'] = object['purpose']
yield ro
# Make request for (next page) JSON data
self.page_number += 1
payload = {
'm': 'home',
'c': 'search',
'a': 'rslist',
'type': '1',
'p': str(self.page_number),
'searchtype': '1'
}
if self.page_number < self.page_num_max:
request = scrapy.FormRequest(url='http://rent.591.com.hk/',
method='GET',
formdata=payload,
headers={'Referer': 'http://rent.591.com.hk/?hl=en-us',
'X-Requested-With': 'XMLHttpRequest'},
callback=self.parse)
request.meta['page_number'] = self.page_number
yield request
这个网站对于一个 scrapy 初学者来说真的不容易 - 所以我整理了这个详细的答案。