我是蟒蛇和scrapy的新手。 我正在尝试抓取种子网址https://www.health.com/patients/status/.This种子网址包含许多网址。但我想从种子网址中仅获取包含Faci / Details /#somenumber的网址。网址如下:
https://www.health.com/patients/status/ ->https://www.health.com/Faci/Details/2
-> https://www.health.com/Faci/Details/3
-> https://www.health.com/Faci/Details/4
https://www.health.com/Faci/Details/2 -> https://www.health.com/provi/details/64
-> https://www.health.com/provi/details/65
https://www.health.com/Faci/Details/3 -> https://www.health.com/provi/details/70
-> https://www.health.com/provi/details/71
在每个https://www.health.com/Faci/Details/2页面内https://www.health.com/provi/details/64 https://www.health.com/provi/details/65 ...最后我想从中获取一些数据 https://www.health.com/provi/details/#somenumber url。我怎样才能达到同样的目标?
截至目前,我已经尝试了scrapy教程中的以下代码,并且只能抓取包含https://www.health.com/Faci/Details/#somenumber的网址。它不会转到https://www.health.com/provi/details/#somenumber。我试图在settings.py文件中设置深度限制但它没有用。
import scrapy
from scrapy.spiders import CrawlSpider, Rule
from scrapy.linkextractors import LinkExtractor
from news.items import NewsItem
class MySpider(CrawlSpider):
name = 'provdetails.com'
allowed_domains = ['health.com']
start_urls = ['https://www.health.com/patients/status/']
rules = (
Rule(LinkExtractor(allow=('/Faci/Details/\d+', )), follow=True),
Rule(LinkExtractor(allow=('/provi/details/\d+', )),callback='parse_item'),
)
def parse_item(self, response):
self.logger.info('Hi, this is an item page! %s', response.url)
item = NewsItem()
item['id'] = response.xpath("//title/text()").extract()
item['name'] = response.xpath("//title/text()").extract()
item['description'] = response.css('p.introduction::text').extract()
filename='details.txt'
with open(filename, 'wb') as f:
f.write(item)
self.log('Saved file %s' % filename)
return item
请帮我继续深造?
答案 0 :(得分:1)
说实话,基于正则表达式和强大的Rule/LinkExtractor
给了我很多时间。对于简单项目,它可能是一种在页面上提取所有链接然后查看href
属性的方法。如果href符合您的需求,yield
一个新的Response
对象。例如:
from scrapy.http import Request
from scrapy.selector import Selector
...
# follow links
for href in sel.xpath('//div[@class="contentLeft"]//div[@class="pageNavigation nobr"]//a').extract():
linktext = Selector(text=href).xpath('//a/text()').extract_first()
if linktext and linktext[0] == "Weiter":
link = Selector(text=href).xpath('//a/@href').extract()[0]
url = response.urljoin(link)
print url
yield Request(url, callback=self.parse)
对您的代码的一些评论:
response.xpath(...).extract()
这将返回一个列表,您可能希望查看提供第一项(或None
)的extract_first()
。
with open(filename, 'wb') as f:
这将多次覆盖该文件。您只能获得最后保存的项目。您也可以以二进制模式('b'
)打开文件。从文件名,我想你想把它作为文本阅读?使用'a'
追加?见open() docs
另一种方法是使用-o
flag来使用scrapys工具将项目存储为JSON或CSV。
return item
这是yield
项目的好方式,而不是返回它们。至少如果您需要从一个页面创建多个项目,则需要yield
。
另一个好方法是:对一种类型/种类的页面使用一个parse()函数。
例如,start_urls
中的每个页面都填入parse()
。通过该提取,您可以使用回调yield
为每个Request
页面提取链接和/Faci/Details/N
parse_faci_details()
。在parse_faci_details()
中,您再次提取感兴趣的链接,创建Request
并通过callback=
将其传递给parse_provi_details()
。
在此功能中,您可以创建所需的项目。