Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Scraping со scrapy и без

Scraping со scrapy и без

Alexander Loschilov

November 27, 2014
Tweet

Other Decks in Programming

Transcript

  1. Что такое scraping? import urllib if __name__ == '__main__': while

    True: f = urllib.urlopen("<URL that is cached>") if f is not None: if "InvalidResponse" in f.read(): print "InvalidResponse is cached." break else: print "There is no InvalidResponse... Clearing cache." print urllib.urlopen("http://localhost:8010/ cache/delete").read()
  2. Web. Что знаем и как работаем? • Web не зависит

    от состояния, то есть функционален по природе. • Состояние существует, но в виде сессий. • Когда мы выполняем последовательность вызовов, мы не думаем о сессии ⟹ нам не хотелось бы думать о деталях сессии при написании кода.
  3. Принцип организации. Session -curl : pycurl.Curl +fetch(request : Request) :

    Response +__init__(url : string) +set_get(params : dict) +set_post(params : dict) +set_json_post(son_body : string) +set_headers(headers : string) <any representation of request> Request +json() : dict +xml() : lxml +text() : string -charset -full_url -headers -http_code Response def make_curl_request(self, curl, callback, header=None): """This is called by Session to set up a curl object for grabbing""" url = str(self.get_full_url()) curl.setopt(pycurl.URL, url) curl.setopt(pycurl.SSLVERSION, pycurl.SSLVERSION_SSLv3) 1 1
  4. Как будет выглядеть код? session = Session() request_1 = Request("<url_2>")

    response_1 = session.fetch(request_1) request_2 = Request("<url_2>") response_2 = session.fetch(request_2)
  5. Appartments Title Price Flight Flights total Usable floor area 2-к

    квартира, 45 м², 3/5 эт. в Нижнем Новгороде 2350000.00 3 5 45 3-к квартира, 134 м², 5/9 эт. в Нижнем Новгороде 12500000.00 5 9 134 1-к квартира, 34 м², 7/19 эт. в Нижнем Новгороде 1900000.00 7 19 34 1-к квартира, 30 м², 7/10 эт. в Нижнем Новгороде 2400000.00 7 19 30 3-к квартира, 68 м², 2/4 эт. в Нижнем Новгороде 3300000.00 2 4 58
  6. Ну, чуть сложнее class AvitoSpider(Spider): name = "avito" allowed_domains =

    ["avito.ru"] start_urls = [ "https://www.avito.ru/nizhniy_novgorod/kvartiry/prodam" ] def parse(self, response): … Spider +parse(response) : Item +name +allowed_domains +start_urls AvitoSpider Item DjangoItem +django_model ApartmentItem
  7. Как ходят данные? start_urls Requests AvitoSpider.parse(response) response as Response avito.ru

    from estate_agencies.models import Agency class DatabaseWriterPipeline(object): def process_item(self, item, spider): print "DatabaseWriterPipeline.process_item" item['agency'] = Agency.objects.get(name=spider.name) item.save() +parse(response) : Item +name +allowed_domains +start_urls AvitoSpider item as Item
  8. Формируем Item def parse(self, response): sel = Selector(response) apartments =

    sel.xpath("//div[contains(@class,'item') and starts-with(@id,'i')]") for apartment in apartments: titles = apartment.xpath("./div/h3[@class='title']/a/@title").extract() deeplinks = apartment.xpath("./div/h3[@class='title']/a/@href").extract() prices = apartment.xpath("./div[3]/div[1]/text()").extract() publication_dates = apartment.xpath("./div[3]/div[2]/div/text()").extract() addresses = apartment.xpath("./div[@class='description']/p[@class='address fader']").extract() for title, deeplink, price, date_published, address in \ zip(titles, deeplinks, prices, publication_dates, addresses): item = ApartmentItem() item["title"] = title item["deeplink"] = ''.join(("http://www.avito.ru", deeplink)) ... yield item