示例#1
0
        async Task RegisterItemsAsync(
            ApplicationDbContext dbContext,
            CrawlContext crawlContext,
            Entry entry,
            HttpResponseMessage response,
            CancellationToken cancellationToken)
        {
            if (response.StatusCode == HttpStatusCode.NotFound ||
                response.StatusCode == HttpStatusCode.Found)
            {
                goto END_CRAWL;
            }
            if (!response.IsSuccessStatusCode)
            {
                logger.LogWarning($"{entry.Url} の取得に失敗しました。({response.StatusCode})");
                return;
            }

            var html = await response.Content.ReadAsStringAsync();

            var document = await parser.ParseAsync(html, cancellationToken);

            var newItems = ExtractItems(document);

            foreach (var newItem in newItems)
            {
                var existedItem = await FindByAsinAsync(
                    dbContext,
                    newItem.Asin,
                    cancellationToken);

                Item item;
                if (existedItem != null)
                {
                    item = existedItem;
                }
                else
                {
                    // 1つのエントリで同じ商品を複数回紹介することがあるので、
                    // 新しい商品は即時登録しておく。
                    dbContext.Items.Add(newItem);
                    await dbContext.SaveChangesAsync(cancellationToken);

                    item = newItem;
                }

                if (!entry.HasItem(item))
                {
                    entry.AddItem(item);
                }

                crawlContext.AddCount();

                logger.LogInformation($"{crawlContext.Count}\t{newItem.Title}\t{entry.Url}");
            }

END_CRAWL:
            entry.MarkAsCrawled();
            dbContext.Entries.Update(entry);
            await dbContext.SaveChangesAsync(cancellationToken);

            logger.LogInformation($"{entry.Url} スクレイピング終了");
        }