Как использовать scrapy для ссылок Amazon.com после кнопки «Далее»?

Я относительно новичок в Python и Scrapy. Я пытаюсь удалить ссылки в разделе «Клиенты, купившие этот товар, также купили». Например: https://rads.stackoverflow.com/amzn/click/com/B001AFF266. Есть 17 страниц для «Клиенты, которые купили этот товар, также купили». Если я попрошу scrapy удалить этот URL-адрес, он удалит только первую страницу (6 элементов). Как мне попросить scrapy нажать кнопку «Далее», чтобы удалить все элементы на 17 страницах? Мы будем очень признательны за пример кода (только та его часть, которая имеет значение в файле crawler.py). Спасибо за ваше время!

В порядке. Вот мой код. Как я уже сказал, я новичок в Python, поэтому код может выглядеть довольно глупо, но он работает, чтобы удалить первую страницу (6 элементов). Я работаю в основном с Fortran или Matlab. Я хотел бы систематически изучать Python, если у меня есть время.

# Code of my crawler.py:

from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.selector import Selector
from beta.items import BetaItem

class AlphaSpider(CrawlSpider):

    name = 'alpha'
    allowed_domains = ['amazon.com']
    start_urls = ['http://www.amazon.com/s/ref=lp_4366_nr_p_n_publication_date_0?rh=n%3A283155%2Cn%3A%211000%2Cn%3A4366%2Cp_n_publication_date%3A1250226011&bbn=4366&ie=UTF8&qid=1384729756&rnid=1250225011']
    rules = (Rule(SgmlLinkExtractor(restrict_xpaths=('//h3/a',)), callback='parse_item'), )

    def parse_item(self, response):
        sel = Selector(response)

        stuff = BetaItem()
    isbn10R = sel.xpath('//li[b[contains(text(),"ISBN-10:")]]/text()').extract()
    isbn10 = []
    if len(isbn10R) > 0:
       isbn10 = [(isbn10R[0].split(' '))[1]]
    stuff['isbn10'] = isbn10

        starsR = sel.xpath('//div[contains(@id,"averageCustomerReviews")]/span/@title').extract()
    stars = []
    if len(starsR) > 0:
       stars = [(starsR[0].split(' '))[0]]
    stuff['stars'] = stars

    reviewsR = sel.xpath('//div[contains(@id,"averageCustomerReviews")]/a[contains(@href,"showViewpoints=1")]/text()').extract()
    reviews = []
    if len(reviewsR) > 0:
       reviews = [(reviewsR[0].split(' '))[0]]
    stuff['reviews'] = reviews

    copsR = sel.xpath('//a[@class="sim-img-title"]/@href').extract()
    ncops = len(copsR)
    cops = [None] * ncops
    if ncops > 0:
       for idx, cop in enumerate(copsR):
           cops[idx]=((cop.split('dp/'))[1].split('/ref'))[0]
    stuff['cops'] = cops       

    return stuff

person maxwell    schedule 08.12.2013    source источник
comment
Буду очень признателен за образец вашего кода   -  person Deck    schedule 08.12.2013
comment
Спасибо, колода, я только что прикрепил код своего сканера.   -  person maxwell    schedule 08.12.2013


Ответы (2)


Насколько я понимаю, вы смогли очистить данные о продукте «Клиенты, которые купили этот товар, также купили». Как вы, наверное, видели, они находятся внутри ul в div с классом "shoveler-content":

<div id="purchaseButtonWrapper" class="shoveler-button-wrapper">
    <a class="back-button" onclick="return false;" style="" href="#Back">
    <div class="shoveler-content">
        <ul tabindex="-1">
            <li class="shoveler-cell" style="margin-left: 16px; margin-right: 16px;">
                <div id="purchase_B003LSTK8G" class="new-faceout p13nimp" data-ref="pd_sim_kstore_1" data-asin="B003LSTK8G">
                ...
                </div>
            </li>
            <li class="shoveler-cell" style="margin-left: 16px; margin-right: 16px;">...</li>
            <li class="shoveler-cell" style="margin-left: 16px; margin-right: 16px;">...</li>
            <li class="shoveler-cell" style="margin-left: 16px; margin-right: 16px;">...</li>
            <li class="shoveler-cell" style="margin-left: 16px; margin-right: 16px;">...</li>
            <li class="shoveler-cell" style="margin-left: 16px; margin-right: 16px;">...</li>
        </ul>
    </div>
    <a class="next-button" onclick="return false;" style="" href="#Next">
        <span class="auiTestSprite s_shvlNext">...</span>
    </a>
    </div>
</div>

Когда вы проверяете сетевую активность выбранного вами браузера (с помощью инструмента Firebug или Chrome Inspect), когда вы нажимаете кнопку «Далее» для следующих предлагаемых продуктов, вы увидите запрос AJAX к URL-адресу такого типа:

http://www.amazon.com
    /gp/product/features/similarities/shoveler/cell-render.html/ref=pd_sim_kstore?
    id=B00261OOWQ,B003XQEVUI,B001NLL5WC,B000FC1KZC,B005G5PPGS,B0043RSJB8,
    B004TSBWYC,B000RH0C8G,B0035IID08,B002AQRVXQ,B005DIAUN6,B000FC10QG
    &pos=7&refTag=pd_sim_kstore&wdg=ebooks_display_on_website
    &shovelerName=purchase

(Я использую эту страницу продукта: https://rads.stackoverflow.com/amzn/click/com/B005CRQ2OE)

В аргументе запроса id находится список ASIN, которые являются следующими предлагаемыми продуктами. 12 ASIN для 6 отображаются? вероятно, некоторое кэширование на странице для следующего «следующего» щелчка, который пользователь, вероятно, сделает.

Что вы получите в результате этого запроса AJAX? В инструменте проверки вашего браузера вы увидите, что ответ имеет тип application/json, а данные ответа представляют собой массив JSON из 12 элементов, каждый из которых какой-то фрагмент HTML, похожий на:

<div class="new-faceout p13nimp" id="purchase_B00261OOWQ" data-asin="B00261OOWQ" data-ref="pd_sim_kstore_7">
    <a href="/Home-Game-Accidental-Guide-Fatherhood-ebook/dp/B00261OOWQ/ref=pd_sim_kstore_7" class="sim-img-title" >
        <div class="product-image">
            <img src="http://ecx.images-amazon.com/images/I/51ZBpvGgsUL._SL500_PIsitb-sticker-arrow-big,TopRight,35,-73_OU01_SS100_.jpg" width="100" alt="" height="100" border="0" /> 
        </div> Home Game: An Accidental Guide to Fatherhood
    </a> 
    <div class="byline">
        <span class="carat">&#8250</span> 
        <a href="http://www.amazon.com/Michael-Lewis/e/B000APZ33E/ref=pd_sim_kstore_bl_7">Michael Lewis</a> 
    </div> 

    <div class="rating-price"> 
        <span class="rating-stars">
            <span class="crAvgStars" style="white-space:no-wrap;">
                <span class="asinReviewsSummary" name="B00261OOWQ">
                    <a href="http://www.amazon.com/Home-Game-Accidental-Guide-Fatherhood-ebook/product-reviews/B00261OOWQ/ref=pd_sim_kstore_cm_cr_acr_img_7">
                        <span class="auiTestSprite s_star_4_0 " title="4.1 out of 5 stars" >
                            <span>4.1 out of 5 stars</span>
                        </span>
                    </a>&nbsp;
                </span>
                (<a href="http://www.amazon.com/Home-Game-Accidental-Guide-Fatherhood-ebook/product-reviews/B00261OOWQ/ref=pd_sim_kstore_cm_cr_acr_txt_7">99</a>)
            </span>
        </span> 
    </div> 
    <div class="binding-platform"> Kindle Edition </div> 
    <div class="pricetext"><span class="price" style="margin-right:5px">$11.36</span></div> 
</div>

Таким образом, вы в основном получаете то, что было в исходном разделе страницы для рекомендуемых продуктов ранее, в каждом <li> из <div class="shoveler-content"><ul>

Но как заставить эти коды ASIN добавляться к параметру id запроса AJAX?

Что ж, на странице продукта вы увидите этот раздел.

<div id="purchaseSimsData" 
    class="sims-data" style="display:none" 
    data-baseAsin="B005CRQ2OE" data-featureId="pd_sim" 
    data-pageId="B005CRQ2OEr_sim_2" data-reftag="pd_sim_kstore"
    data-wdg="ebooks_display_on_website" data-widgetName="purchase">
    B003LSTK8G,B000VKVZR6,B003E20ZRY,B000RH0C9A,B000RH0CA4,B000YMDQRS,
    B00261OOWQ,B003XQEVUI,B001NLL5WC,B000FC1KZC,B005G5PPGS,B0043RSJB8,
    B004TSBWYC,B000RH0C8G,B0035IID08,B002AQRVXQ,B005DIAUN6,B000FC10QG,
    B0018QQQKS,B002OTKEP6,B005PUWUKS,B007V65R54,B00B3VOTTI,B004EYT932,
    B002UBRFFU,B000WJSB50,B000RH0DYE,B004JXXKWY,B003E8AJXI,B008TRU7PE,
    B00555X8OA,B007OSIOWM,B00DLJIA54,B00139XTG4,B0058Z4NR8,B00ALBR6JG,
    B004H0M8QS,B003F3PL7Q,B008UX8YPC,B000U913GG,B003HOXLVQ,B000VWM0MI,
    B000SEIU28,B006VE7YS0,B008KPMBIG,B003CIQ57E,B0064EHZY0,B008UX3ITE,
    B001NLKY38,B003VIWK4C,B005GSYZRA,B007YGGOVM,B004H4X84K,B00B5ZQ72Y,
    B000R1BAH4,B008W02TIG,B000W8HC8I,B0036QVOKU,B000VRBBDC,B00APDGFOC,
    B00EOAS0EK,B000QCS888,B001QIGZEK,B0074B55IK,B000FC12C8,B00AP2XVJ0,
    B000FCK5YE,B006ID6UAW,B001FA0W5W,B005HFI0X2,B006ZOYM9K,B003SNJZ3Y,
    B00C1N5WOI,B008EKORIY,B00C4GRK4W,B004V3WRNU,B00BV6RTUG,B001AFF266,
    B00DUM1W3E,B00APDGGCS,B008WOUFIS,B008EKOO46,B008JHXO6S,B005AJM3U6,
    B00BKRW6GI,B00CDUVSQ0,B00A287PG2,B009H679WA,B000VDUWMC,B009NF6IRW
</div>

который выглядит как все предлагаемые продукты ASIN.

Поэтому я предлагаю вам эмулировать последовательные запросы AJAX, чтобы получить предлагаемые продукты, 12 ASIN за раз, декодировать ответ с помощью пакета json, а затем анализировать каждый фрагмент HTML для извлечения нужной информации о продукте.

person paul trmbrth    schedule 08.12.2013
comment
На самом деле, если мне нужны только те ASIN похожих предметов (т. е. совместно приобретенные предметы), мне нужно только удалить xpath//div[ @id=purchaseSimsData], и мне не нужно эмулировать запросы AJAX, которые в любом случае я не делаю. не знаю, как сделать...? Я был так глуп, что пропустил этот xpath, который содержит все ASIN. Большое спасибо за подробные инструкции и помощь! - person maxwell; 09.12.2013
comment
Что ж, именно при поиске этих ASIN в URL-адресе запроса AJAX я нашел часть HTML, содержащую эти ASIN. Если вам не нужна подробная информация о продуктах таким образом, вам действительно не нужен вызов AJAX, просто проанализируйте <div id="purchaseSimsData"... - person paul trmbrth; 09.12.2013

Я бы порекомендовал вам избегать скрапинга, особенно если вы новичок. Используйте замечательный модуль запросов для загрузки страниц https://github.com/kennethreitz/requests.

и BeautifulSoup для анализа веб-страниц. http://www.crummy.com/software/BeautifulSoup/.

person Goranek    schedule 08.12.2013
comment
Спасибо за предложения. Но решат ли они проблему, которую потенциально не решит скрейпинг? Я надеюсь, что вы могли бы помочь мне с проблемой использования scrapy. - person maxwell; 09.12.2013