J'essaie d'extraire des informations sur les produits d'une page Web à l'aide de scrapy. Ma page Web à effacer ressemble à ceci:
J'ai essayé de reproduire le prochain bouton-appel-ajax mais je ne peux pas travailler, alors j'essaie Selenium. Je peux exécuter le WebDriver de Selenium dans un script séparé, mais je ne sais pas comment intégrer Scrapy. Où vais-je mettre la partie sélénium dans mon araignée raclante?
Mon araignée est assez standard, comme suit:
class ProductSpider(CrawlSpider):
name = "product_spider"
allowed_domains = ['example.com']
start_urls = ['http://example.com/shanghai']
rules = [
Rule(SgmlLinkExtractor(restrict_xpaths='//div[@id="productList"]//dl[@class="t2"]//dt'), callback='parse_product'),
]
def parse_product(self, response):
self.log("parsing product %s" %response.url, level=INFO)
hxs = HtmlXPathSelector(response)
# actual data follows
Toute idée est appréciée. Merci!
Cela dépend vraiment de la manière dont vous devez gratter le site et des données que vous souhaitez obtenir.
Voici un exemple de suivi de la pagination sur eBay avec Scrapy
+ Selenium
:
import scrapy
from Selenium import webdriver
class ProductSpider(scrapy.Spider):
name = "product_spider"
allowed_domains = ['ebay.com']
start_urls = ['http://www.ebay.com/sch/i.html?_odkw=books&_osacat=0&_trksid=p2045573.m570.l1313.TR0.TRC0.Xpython&_nkw=python&_sacat=0&_from=R40']
def __init__(self):
self.driver = webdriver.Firefox()
def parse(self, response):
self.driver.get(response.url)
while True:
next = self.driver.find_element_by_xpath('//td[@class="pagn-next"]/a')
try:
next.click()
# get the data and write it to scrapy items
except:
break
self.driver.close()
Voici quelques exemples d '"araignées au sélénium":
Il existe également une alternative à l’utilisation de Selenium
avec Scrapy
. Dans certains cas, utiliser ScrapyJS
middleware suffit à gérer les parties dynamiques d'une page. Exemple d'utilisation dans le monde réel:
Si (l'URL ne change pas entre les deux pages), vous devez ajouter dont_filter = True avec votre scrapy.Request () ou scrapy trouvera cette url en double après le traitement de la première page.
Si vous avez besoin de rendre des pages avec JavaScript, vous devez utiliser scrapy-splash , vous pouvez également vérifier ceci middleware scrapy qui peut gérer les pages javascript avec Selenium ou vous pouvez le faire en lançant n'importe quel navigateur sans tête
Mais la solution la plus efficace et la plus rapide est d’examiner votre navigateur et de voir quelles demandes sont faites lors de la soumission d’un formulaire ou du déclenchement d’un événement donné. Essayez de simuler les mêmes requêtes que celles envoyées par votre navigateur. Si vous pouvez répliquer correctement les demandes, vous obtiendrez les données dont vous avez besoin.
Voici un exemple :
class ScrollScraper(Spider):
name = "scrollingscraper"
quote_url = "http://quotes.toscrape.com/api/quotes?page="
start_urls = [quote_url + "1"]
def parse(self, response):
quote_item = QuoteItem()
print response.body
data = json.loads(response.body)
for item in data.get('quotes', []):
quote_item["author"] = item.get('author', {}).get('name')
quote_item['quote'] = item.get('text')
quote_item['tags'] = item.get('tags')
yield quote_item
if data['has_next']:
next_page = data['page'] + 1
yield Request(self.quote_url + str(next_page))
Lorsque l'URL de la pagination est identique pour toutes les pages et utilise POST demande, vous pouvez utiliser scrapy.FormRequest () () au lieu de scrapy.Request () , les deux sont identiques mais FormRequest ajoute un nouvel argument ( formdata = ) au constructeur.
Voici un autre exemple d'araignée de cette post :
class SpiderClass(scrapy.Spider):
# spider name and all
name = 'ajax'
page_incr = 1
start_urls = ['http://www.pcguia.pt/category/reviews/#paginated=1']
pagination_url = 'http://www.pcguia.pt/wp-content/themes/flavor/functions/ajax.php'
def parse(self, response):
sel = Selector(response)
if self.page_incr > 1:
json_data = json.loads(response.body)
sel = Selector(text=json_data.get('content', ''))
# your code here
# pagination code starts here
if sel.xpath('//div[@class="panel-wrapper"]'):
self.page_incr += 1
formdata = {
'sorter': 'recent',
'location': 'main loop',
'loop': 'main loop',
'action': 'sort',
'view': 'grid',
'columns': '3',
'paginated': str(self.page_incr),
'currentquery[category_name]': 'reviews'
}
yield FormRequest(url=self.pagination_url, formdata=formdata, callback=self.parse)
else:
return