【问题标题】:web Crawling and Extracting data using scrapy使用scrapy进行网络抓取和提取数据
【发布时间】:2017-08-04 07:33:09
【问题描述】:

我是 python 和 scrapy 的新手。 我正在尝试抓取种子网址https://www.health.com/patients/status/.This 种子网址包含许多网址。但我只想从种子 url 中获取包含 Faci/Details/#somenumber 的 url。url 如下所示:

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

请帮我继续下一步?

【问题讨论】:

    标签: python-2.7 web-scraping scrapy web-crawler scrapy-spider


    【解决方案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() 
    

    这将返回一个列表,也许您想查看提供第一项的extract_first()(或None)。

        with open(filename, 'wb') as f:
    

    这将多次覆盖文件。您只会获得最后保存的项目。您还可以以二进制模式 ('b') 打开文件。从文件名中我猜您想将其作为文本阅读?使用'a' 追加?见open() docs 另一种方法是使用-o flag 使用scrapys 工具将项目存储为JSON 或CSV。

        return item
    

    yield 物品而不是退货是一种很好的风格。至少如果您需要从一个页面创建多个项目,您需要yield 他们。

    另一个好方法是:对一种类型/种类的页面使用一个 parse() 函数

    例如,start_urls 中的每一页都以 parse() 结尾。从中提取的内容可以为每个带有回调 parse_faci_details()/Faci/Details/N 页面提取链接和 yield Requests。在parse_faci_details() 中,您再次提取感兴趣的链接,创建Requests 并通过callback= 将它们传递给例如parse_provi_details()。 在此函数中,您可以创建所需的项目。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-05-04
      • 1970-01-01
      • 2023-04-03
      • 2021-01-13
      • 2014-08-16
      相关资源
      最近更新 更多