Written by - Hugo Billé Martins
Por que o scrapy?
Recentemente comecei um projeto que envolve um cado de botânica, o nome dele é §YggdrasilProject e basicamente vou utiliza-lo para cadastrar as plantas que tenho aqui em casa. Enfim, para começar o projeto eu primeiro precisava encontrar todas as espécies de plantas catalogadas para registrar qual é a espécie de cada planta daqui de casa. Até esse momento eu não sabia bem a quantidade de dados que essa empreitada geraria mas depois de terminar, consegui um total de 563.811 espécies.
Mas de onde eu consegui esse tanto de planta? Infelizmente não achei uma API com esses dados, o que tornaria esse desafio bem mais fácil; o que eu achei foi um site chamado §The Plant List que, como o nome sugeri, é uma lista de plantas.
Antes de entrar para o código, vamos entender como é a estrutura das páginas. 1. indo para o §catálogo, vamos nos deparar com os quatro grupos do reino plantae: Angiosperma, Gimnosperma, Pteridófitas e Briófitas 2. Clicando em qualquer um dos grupos, entramos na lista de famílias do respectivo grupo. Com uma simples query no sql podemos ver que o grupo Angiosperma tem 412 famílias, então já podemos esperar que esse grupo vai ser o que mais vai dar trabalho. Na imagem abaixo temos o número de famílias dos outros grupos: 3. Clicando em qualquer uma das famílias, vamos encontrar todas os gêneros dessa família. 4. E finalmente, clicando em qualquer um dos gêneros, vamos encontrar a lista de todas as espécies desse gênero.
Como obeter esses dados
Em um mundo ideal, esse site teria uma API com todos esses dados, mas esse não é o caso. O site em si já foi transferido para o §WFO Plant List, mas ele aparentemente também não tem uma API ou um csv milagroso com os dados que eu quero. Enfim, o jeito é usar um web crawler para percorrer cada cada grupo, cada família desse grupo, cada gênero de cada família de cada grupo, e finalmente pegar cada spécie de cada gênero de cada família de cada grupo. Ufa! colocando desse jeito parece que foi um inferno fazer isso mas garanto que não foi tão complicado assim.
Usando o scrapy
Scrapy é uma framework para python que ajuda imensamente a criar web crawlers. Eu consegui fazer todo o código que vou apresentar aqui lendo a documentação e lendo algumas coisas aleatórias no StackOverflow, não há necessidade de ver um curso só para aprender scrapy.
Instalação
Como é de costume para qualquer pacote no python:
$ pip install scrapy
O scrapy já vai te dar uma comando para criar um novo projeto com todas as configurações prontas para você.
scrapy startproject tutorial
Isso vai criar uma pastinha com as configurações do scrapy e uma outra pasta onde você vai programar seus web crawlers (aqui chamados de "spiders"). A única coisa que vamos mexer no momento vai ser no setting.py dentro da pasta do projeto; adicione a seguinte linha de código HTTPERROR_ALLOWED_CODES =[404] em qualquer parte do arquivo, para garantir que, se nossa spider se deparar com um erro 404 ela não vai parar de executar o programa (vai ser muito importante para esse projeto porque tem alguns links quebrados no site).
Começando o projeto
Vamos concordar que para pegar os 4 grupos não há necessidade de fazer um programa kkkkkk, eu no caso só escrevi eles em um arquivo .csv, que pode ser encontrado [aqui] (https://github.com/pixelmancer-64/WebCrawlers/blob/master/yggdrasil/Groups/groups.csv). Mas para pegar todas as famílias já há a necessidade da gente utilizar um webcrawler.
Famílias
Continua sendo poucos registros,apenas 652. Não vai valer muito a pena eu explicar como é o funcionamento do scapy com esse exemplo. Se desejar o .csv com as famílias de cada grupo, é só acessar novamente meu [repositório] (https://github.com/pixelmancer-64/WebCrawlers/blob/master/yggdrasil/Families/).
Gêneros
Agora as coisas começam a ficar interessantes. Para obter os gêneros vamos precisar acessar todas as famílias de cada grupo para que possamos coletar a lista de gêneros de cada família.
Vamos começar importando o scrapy e classe que extende da scrapy.Spider
. Vamos
definir um nome e a url inicial onde o nosso crawler vai começar. Assim que ele obter
a página inicial, o crawler (ou Spider, chame da forma que preferir), vai obter todos
os matchs da query response.css('ul#nametree li i')
, que vai retornar um array
de elementos da página e, posteriormente, vamos acessar o texto dentro desses elementos.
Vai ser um pouco complicado entender as próximas partes sem entender um pouco sobre
o funcionamento do yeild, então recomendo ler um pouco sobre antes de prosseguir.
Enfim, o próximo passo é iterar o array que obtemos do response.css()
e, para
cada valor, vamos dar um "yeild" em um objeto com o nome (o texto dentro desse elemento
html), e o id da família correspondente a esse gênero. Quando formos executar o comando
para salvar o retorno do crawler em um arquivo ele vai pegar esse monte de objetos
que estamos retornando pelo yeild e escrever no arquivo.
Pegamos esse array de famílias e, para cada família, entramos em sua respectiva páginas, coletamos todos os gêneros dessa família e retornamos, continuando esse processo até que tenhamos todas as famílias e seus gêneros.
_23import scrapy_23_23 Angiosperm = ['Acanthaceae', 'Achariaceae', 'Achatocarpaceae', 'Acoraceae', 'Actinidiaceae', 'Adoxaceae', 'Aextoxicaceae', 'Aizoaceae', 'Akaniaceae', 'Alismataceae', 'Alseuosmiaceae', 'Alstroemeriaceae', 'Altingiaceae', 'Amaranthaceae', 'Amaryllidaceae', 'Amborellaceae', 'Anacampserotaceae', 'Anacardiaceae', 'Anarthriaceae', 'Ancistrocladaceae', 'Anisophylleaceae', 'Annonaceae', 'Aphanopetalaceae', 'Aphloiaceae', 'Apiaceae', 'Apocynaceae', 'Apodanthaceae', 'Aponogetonaceae', 'Aquifoliaceae', 'Araceae', 'Araliaceae', 'Arecaceae', 'Argophyllaceae', 'Aristolochiaceae', 'Asparagaceae', 'Asteliaceae', 'Asteropeiaceae', 'Atherospermataceae', 'Austrobaileyaceae', 'Balanopaceae', 'Balanophoraceae', 'Balsaminaceae', 'Barbeuiaceae', 'Barbeyaceae', 'Basellaceae', 'Bataceae', 'Begoniaceae', 'Berberidaceae', 'Berberidopsidaceae', 'Betulaceae', 'Biebersteiniaceae', 'Bignoniaceae', 'Bixaceae', 'Blandfordiaceae', 'Bonnetiaceae', 'Boraginaceae', 'Boryaceae', 'Brassicaceae', 'Bromeliaceae', 'Brunelliaceae', 'Bruniaceae', 'Burmanniaceae', 'Burseraceae', 'Butomaceae', 'Buxaceae', 'Byblidaceae', 'Cabombaceae', 'Cactaceae', 'Calceolariaceae', 'Calophyllaceae', 'Calycanthaceae', 'Calyceraceae', 'Campanulaceae', 'Campynemataceae', 'Canellaceae', 'Cannabaceae', 'Cannaceae', 'Capparaceae', 'Caprifoliaceae', 'Cardiopteridaceae', 'Caricaceae', 'Carlemanniaceae', 'Caryocaraceae', 'Caryophyllaceae', 'Casuarinaceae', 'Celastraceae', 'Centrolepidaceae', 'Centroplacaceae', 'Cephalotaceae', 'Ceratophyllaceae', 'Cercidiphyllaceae', 'Chloranthaceae', 'Chrysobalanaceae', 'Circaeasteraceae', 'Cistaceae', 'Cleomaceae', 'Clethraceae', 'Clusiaceae', 'Colchicaceae', 'Columelliaceae', 'Combretaceae', 'Commelinaceae', 'Compositae', 'Connaraceae', 'Convolvulaceae', 'Coriariaceae', 'Cornaceae', 'Corsiaceae', 'Corynocarpaceae', 'Costaceae', 'Crassulaceae', 'Crossosomataceae', 'Ctenolophonaceae', 'Cucurbitaceae', 'Cunoniaceae', 'Curtisiaceae', 'Cyclanthaceae', 'Cymodoceaceae', 'Cynomoriaceae', 'Cyperaceae', 'Cyrillaceae', 'Cytinaceae', 'Daphniphyllaceae', 'Dasypogonaceae', 'Datiscaceae', 'Degeneriaceae', 'Diapensiaceae', 'Dichapetalaceae', 'Didiereaceae', 'Dilleniaceae', 'Dioncophyllaceae', 'Dioscoreaceae', 'Dipentodontaceae', 'Dipterocarpaceae', 'Dirachmaceae', 'Doryanthaceae', 'Droseraceae', 'Drosophyllaceae', 'Ebenaceae', 'Ecdeiocoleaceae', 'Elaeagnaceae', 'Elaeocarpaceae', 'Elatinaceae', 'Emblingiaceae', 'Ericaceae', 'Eriocaulaceae', 'Erythroxylaceae', 'Escalloniaceae', 'Eucommiaceae', 'Euphorbiaceae', 'Euphroniaceae', 'Eupomatiaceae', 'Eupteleaceae', 'Fagaceae', 'Flacourtiaceae', 'Flagellariaceae', 'Fouquieriaceae', 'Frankeniaceae', 'Garryaceae', 'Geissolomataceae', 'Gelsemiaceae', 'Gentianaceae', 'Geraniaceae', 'Gerrardinaceae', 'Gesneriaceae', 'Gisekiaceae', 'Gomortegaceae', 'Goodeniaceae', 'Goupiaceae', 'Grossulariaceae', 'Grubbiaceae', 'Guamatelaceae', 'Gunneraceae', 'Gyrostemonaceae', 'Haemodoraceae', 'Halophytaceae', 'Haloragaceae', 'Hamamelidaceae', 'Hanguanaceae', 'Haptanthaceae', 'Heliconiaceae', 'Helwingiaceae', 'Hernandiaceae', 'Himantandraceae', 'Huaceae', 'Humiriaceae', 'Hydatellaceae', 'Hydnoraceae', 'Hydrangeaceae', 'Hydrocharitaceae', 'Hydroleaceae', 'Hydrostachyaceae', 'Hypericaceae', 'Hypoxidaceae', 'Icacinaceae', 'Iridaceae', 'Irvingiaceae', 'Iteaceae', 'Ixioliriaceae', 'Ixonanthaceae', 'Joinvilleaceae', 'Juglandaceae', 'Juncaceae', 'Juncaginaceae',_23_23TIPO = 'A'_23ARRAYZAO = A_23_23class GeneraSpider(scrapy.Spider):_23 name = 'genera'_23 increment = 1_23 start_urls = [_23 'http://www.theplantlist.org/1.1/browse/'+TIPO+'/'+ARRAYZAO[0]+'/']_23_23 def parse(self, response):_23 families = response.css('ul#nametree li i')_23_23 for family in families:_23_23 yield {'name': family.css('::text').get(), 'family_id': self.increment + 0}_23_23 self.increment += 1_23_23 yield scrapy.Request('http://www.theplantlist.org/1.1/browse/'+TIPO+'/'+ARRAYZAO[self.increment-1])
Enfim, os arquivos csv podem ser encontrados §aqui, você pode optar tanto pelos arquivos separados por grupo ou um único arquivo com todos os gêneros.
Espécies
Se em algum momento você pretende utilizar o código desse projeto como base, recomendo utilizar esse aqui logo em seguida. É de longe o mais completo e provavelmente vai ser base para outras situações bem parecidas.
_50_50import scrapy_50import csv_50from scrapy.spidermiddlewares.httperror import HttpError_50_50A = ['Acanthaceae', 'Achariaceae', 'Achatocarpaceae', 'Acoraceae', 'Actinidiaceae', 'Adoxaceae', 'Aextoxicaceae', 'Aizoaceae', 'Akaniaceae', 'Alismataceae', 'Alseuosmiaceae', 'Alstroemeriaceae', 'Altingiaceae', 'Amaranthaceae', 'Amaryllidaceae', 'Amborellaceae', 'Anacampserotaceae', 'Anacardiaceae', 'Anarthriaceae', 'Ancistrocladaceae', 'Anisophylleaceae', 'Annonaceae', 'Aphanopetalaceae', 'Aphloiaceae', 'Apiaceae', 'Apocynaceae', 'Apodanthaceae', 'Aponogetonaceae', 'Aquifoliaceae', 'Araceae', 'Araliaceae', 'Arecaceae', 'Argophyllaceae', 'Aristolochiaceae', 'Asparagaceae', 'Asteliaceae', 'Asteropeiaceae', 'Atherospermataceae', 'Austrobaileyaceae', 'Balanopaceae', 'Balanophoraceae', 'Balsaminaceae', 'Barbeuiaceae', 'Barbeyaceae', 'Basellaceae', 'Bataceae', 'Begoniaceae', 'Berberidaceae', 'Berberidopsidaceae', 'Betulaceae', 'Biebersteiniaceae', 'Bignoniaceae', 'Bixaceae', 'Blandfordiaceae', 'Bonnetiaceae', 'Boraginaceae', 'Boryaceae', 'Brassicaceae', 'Bromeliaceae', 'Brunelliaceae', 'Bruniaceae', 'Burmanniaceae', 'Burseraceae', 'Butomaceae', 'Buxaceae', 'Byblidaceae', 'Cabombaceae', 'Cactaceae', 'Calceolariaceae', 'Calophyllaceae', 'Calycanthaceae', 'Calyceraceae', 'Campanulaceae', 'Campynemataceae', 'Canellaceae', 'Cannabaceae', 'Cannaceae', 'Capparaceae', 'Caprifoliaceae', 'Cardiopteridaceae', 'Caricaceae', 'Carlemanniaceae', 'Caryocaraceae', 'Caryophyllaceae', 'Casuarinaceae', 'Celastraceae', 'Centrolepidaceae', 'Centroplacaceae', 'Cephalotaceae', 'Ceratophyllaceae', 'Cercidiphyllaceae', 'Chloranthaceae', 'Chrysobalanaceae', 'Circaeasteraceae', 'Cistaceae', 'Cleomaceae', 'Clethraceae', 'Clusiaceae', 'Colchicaceae', 'Columelliaceae', 'Combretaceae', 'Commelinaceae', 'Compositae', 'Connaraceae', 'Convolvulaceae', 'Coriariaceae', 'Cornaceae', 'Corsiaceae', 'Corynocarpaceae', 'Costaceae', 'Crassulaceae', 'Crossosomataceae', 'Ctenolophonaceae', 'Cucurbitaceae', 'Cunoniaceae', 'Curtisiaceae', 'Cyclanthaceae', 'Cymodoceaceae', 'Cynomoriaceae', 'Cyperaceae', 'Cyrillaceae', 'Cytinaceae', 'Daphniphyllaceae', 'Dasypogonaceae', 'Datiscaceae', 'Degeneriaceae', 'Diapensiaceae', 'Dichapetalaceae', 'Didiereaceae', 'Dilleniaceae', 'Dioncophyllaceae', 'Dioscoreaceae', 'Dipentodontaceae', 'Dipterocarpaceae', 'Dirachmaceae', 'Doryanthaceae', 'Droseraceae', 'Drosophyllaceae', 'Ebenaceae', 'Ecdeiocoleaceae', 'Elaeagnaceae', 'Elaeocarpaceae', 'Elatinaceae', 'Emblingiaceae', 'Ericaceae', 'Eriocaulaceae', 'Erythroxylaceae', 'Escalloniaceae', 'Eucommiaceae', 'Euphorbiaceae', 'Euphroniaceae', 'Eupomatiaceae', 'Eupteleaceae', 'Fagaceae', 'Flacourtiaceae', 'Flagellariaceae', 'Fouquieriaceae', 'Frankeniaceae', 'Garryaceae', 'Geissolomataceae', 'Gelsemiaceae', 'Gentianaceae', 'Geraniaceae', 'Gerrardinaceae', 'Gesneriaceae', 'Gisekiaceae', 'Gomortegaceae', 'Goodeniaceae', 'Goupiaceae', 'Grossulariaceae', 'Grubbiaceae', 'Guamatelaceae', 'Gunneraceae', 'Gyrostemonaceae', 'Haemodoraceae', 'Halophytaceae', 'Haloragaceae', 'Hamamelidaceae', 'Hanguanaceae', 'Haptanthaceae', 'Heliconiaceae', 'Helwingiaceae', 'Hernandiaceae', 'Himantandraceae', 'Huaceae', 'Humiriaceae', 'Hydatellaceae', 'Hydnoraceae', 'Hydrangeaceae', 'Hydrocharitaceae', 'Hydroleaceae', 'Hydrostachyaceae', 'Hypericaceae', 'Hypoxidaceae', 'Icacinaceae', 'Iridaceae', 'Irvingiaceae', 'Iteaceae', 'Ixioliriaceae', 'Ixonanthaceae', 'Joinvilleaceae', 'Juglandaceae', 'Juncaceae', 'Juncaginaceae',_50 'Kirkiaceae', 'Koeberliniaceae', 'Krameriaceae', 'Lacistemataceae', 'Lactoridaceae', 'Lamiaceae', 'Lanariaceae', 'Lardizabalaceae', 'Lauraceae', 'Lecythidaceae', 'Leguminosae', 'Lentibulariaceae', 'Lepidobotryaceae', 'Liliaceae', 'Limeaceae', 'Limnanthaceae', 'Linaceae', 'Linderniaceae', 'Loasaceae', 'Loganiaceae', 'Lophiocarpaceae', 'Lophopyxidaceae', 'Loranthaceae', 'Lowiaceae', 'Lythraceae', 'Magnoliaceae', 'Malpighiaceae', 'Malvaceae', 'Marantaceae', 'Marcgraviaceae', 'Martyniaceae', 'Mayacaceae', 'Melanthiaceae', 'Melastomataceae', 'Meliaceae', 'Melianthaceae', 'Menispermaceae', 'Menyanthaceae', 'Metteniusaceae', 'Misodendraceae', 'Mitrastemonaceae', 'Molluginaceae', 'Monimiaceae', 'Montiaceae', 'Montiniaceae', 'Moraceae', 'Moringaceae', 'Muntingiaceae', 'Musaceae', 'Myodocarpaceae', 'Myricaceae', 'Myristicaceae', 'Myrothamnaceae', 'Myrtaceae', 'Nartheciaceae', 'Nelumbonaceae', 'Nepenthaceae', 'Neuradaceae', 'Nitrariaceae', 'Nothofagaceae', 'Nyctaginaceae', 'Nymphaeaceae', 'Ochnaceae', 'Olacaceae', 'Oleaceae', 'Onagraceae', 'Oncothecaceae', 'Opiliaceae', 'Orchidaceae', 'Orobanchaceae', 'Oxalidaceae', 'Paeoniaceae', 'Pandaceae', 'Pandanaceae', 'Papaveraceae', 'Paracryphiaceae', 'Passifloraceae', 'Paulowniaceae', 'Pedaliaceae', 'Penaeaceae', 'Pennantiaceae', 'Pentadiplandraceae', 'Pentaphragmataceae', 'Pentaphylacaceae', 'Penthoraceae', 'Peraceae', 'Peridiscaceae', 'Petenaeaceae', 'Petermanniaceae', 'Petrosaviaceae', 'Phellinaceae', 'Philesiaceae', 'Philydraceae', 'Phrymaceae', 'Phyllanthaceae', 'Phyllonomaceae', 'Physenaceae', 'Phytolaccaceae', 'Picramniaceae', 'Picrodendraceae', 'Piperaceae', 'Pittosporaceae', 'Plantaginaceae', 'Platanaceae', 'Plocospermataceae', 'Plumbaginaceae', 'Poaceae', 'Podostemaceae', 'Polemoniaceae', 'Polygalaceae', 'Polygonaceae', 'Pontederiaceae', 'Portulacaceae', 'Posidoniaceae', 'Potamogetonaceae', 'Primulaceae', 'Proteaceae', 'Putranjivaceae', 'Quillajaceae', 'Rafflesiaceae', 'Ranunculaceae', 'Rapateaceae', 'Resedaceae', 'Restionaceae', 'Rhabdodendraceae', 'Rhamnaceae', 'Rhipogonaceae', 'Rhizophoraceae', 'Roridulaceae', 'Rosaceae', 'Rousseaceae', 'Rubiaceae', 'Ruppiaceae', 'Rutaceae', 'Sabiaceae', 'Salicaceae', 'Salvadoraceae', 'Santalaceae', 'Sapindaceae', 'Sapotaceae', 'Sarcobataceae', 'Sarcolaenaceae', 'Sarraceniaceae', 'Saururaceae', 'Saxifragaceae', 'Scheuchzeriaceae', 'Schisandraceae', 'Schlegeliaceae', 'Schoepfiaceae', 'Scrophulariaceae', 'Setchellanthaceae', 'Simaroubaceae', 'Simmondsiaceae', 'Siparunaceae', 'Sladeniaceae', 'Smilacaceae', 'Solanaceae', 'Sphaerosepalaceae', 'Sphenocleaceae', 'Stachyuraceae', 'Staphyleaceae', 'Stegnospermataceae', 'Stemonaceae', 'Stemonuraceae', 'Stilbaceae', 'Strasburgeriaceae', 'Strelitziaceae', 'Stylidiaceae', 'Styracaceae', 'Surianaceae', 'Symplocaceae', 'Talinaceae', 'Tamaricaceae', 'Tapisciaceae', 'Tecophilaeaceae', 'Tetrachondraceae', 'Tetramelaceae', 'Tetrameristaceae', 'Theaceae', 'Thomandersiaceae', 'Thurniaceae', 'Thymelaeaceae', 'Ticodendraceae', 'Tofieldiaceae', 'Torricelliaceae', 'Tovariaceae', 'Trigoniaceae', 'Trimeniaceae', 'Triuridaceae', 'Trochodendraceae', 'Tropaeolaceae', 'Typhaceae', 'Ulmaceae', 'Urticaceae', 'Vahliaceae', 'Velloziaceae', 'Verbenaceae', 'Violaceae', 'Vitaceae', 'Vivianiaceae', 'Vochysiaceae', 'Winteraceae', 'Xanthorrhoeaceae', 'Xeronemataceae', 'Xyridaceae', 'Zingiberaceae', 'Zosteraceae', 'Zygophyllaceae']_50_50# G = ['Araucariaceae', 'Cupressaceae', 'Cycadaceae', 'Ephedraceae', 'Ginkgoaceae', 'Gnetaceae',_50# 'Pinaceae', 'Podocarpaceae', 'Sciadopityaceae', 'Taxaceae', 'Welwitschiaceae', 'Zamiaceae']_50_50# P = ['Anemiaceae', 'Apleniaceae', 'Aspleniaceae', 'Athyriaceae', 'Blechnaceae', 'Cibotiaceae', 'Culcitaceae', 'Cyatheaceae', 'Cystodiaceae', 'Cystopteridaceae', 'Davalliaceae', 'Dennstaedtiaceae', 'Dicksoniaceae', 'Diplaziopsidaceae', 'Dipteridaceae', 'Dryopteridacae', 'Dryopteridaceae', 'Equisetaceae', 'Gleicheniaceae', 'Hymenophyllaceae', 'Hypodematiaceae', 'Isoëtaceae', 'Lindsaeaceae', 'Lomariopsidaceae', 'Lonchitidaceae', 'Loxsomataceae', 'Lycopodiaceae', 'Lygodiaceae', 'Marattiaceae', 'Marsileaceae', 'Matoniaceae', 'Metaxyaceae', 'Nephrolepidaceae', 'Oleandraceae', 'Onocleaceae', 'Ophioglossaceae', 'Osmundaceae', 'Plagiogyriaceae', 'Polypodiaceae', 'Psilotaceae', 'Pteridaceae', 'Rhachidosoraceae', 'Saccolomataceae', 'Salviniaceae', 'Schizaeaceae', 'Selaginellaceae', 'Tectariaceae', 'Thelypteridaceae', 'Thyrsopteridaceae', 'Woodsiaceae']_50#_50_50# B = ['Acrobolbaceae', 'Adelanthaceae', 'Allisoniaceae', 'Amblystegiaceae', 'Anastrophyllaceae', 'Andreaeaceae', 'Andreaeobryaceae', 'Aneuraceae', 'Antheliaceae', 'Anthocerotaceae', 'Archidiaceae', 'Arnelliaceae', 'Aulacomniaceae', 'Aytoniaceae', 'Balantiopsaceae', 'Bartramiaceae', 'Blasiaceae', 'Brachytheciaceae', 'Brevianthaceae', 'Bruchiaceae', 'Bryaceae', 'Bryobartramiaceae', 'Bryoxiphiaceae', 'Buxbaumiaceae', 'Calomniaceae', 'Calymperaceae', 'Calypogeiaceae', 'Catagoniaceae', 'Catoscopiaceae', 'Cephaloziaceae', 'Cephaloziellaceae', 'Chaetophyllopsaceae', 'Chonecoleaceae', 'Cinclidotaceae', 'Cleveaceae', 'Climaciaceae', 'Conocephalaceae', 'Corsiniaceae', 'Cryphaeaceae', 'Cyrtopodaceae', 'Daltoniaceae', 'Dendrocerotaceae', 'Dicnemonaceae', 'Dicranaceae', 'Diphysciaceae', 'Disceliaceae', 'Ditrichaceae', 'Echinodiaceae', 'Encalyptaceae', 'Entodontaceae', 'Ephemeraceae', 'Erpodiaceae', 'Eustichiaceae', 'Exormothecaceae', 'Fabroniaceae', 'Fissidentaceae', 'Fontinalaceae', 'Fossombroniaceae', 'Funariaceae', 'Geocalycaceae', 'Gigaspermaceae', 'Goebeliellaceae', 'Grimmiaceae', 'Gymnomitriaceae', 'Gyrothyraceae', 'Haplomitriaceae', 'Hedwigiaceae', 'Helicophyllaceae', 'Herbertaceae', 'Hookeriaceae', 'Hylocomiaceae', 'Hymenophytaceae', 'Hypnaceae', 'Hypnodendraceae', 'Hypopterygiaceae', 'Jackiellaceae', 'Jubulaceae', 'Jubulopsaceae', 'Jungermanniaceae', 'Lejeuneaceae', 'Lembophyllaceae', 'Lepicoleaceae', 'Lepidolaenaceae', 'Lepidoziaceae', 'Leptodontaceae', 'Lepyrodontaceae', 'Leskeaceae', 'Leucodontaceae', 'Leucomiaceae', 'Lophocoleaceae',_50# 'Lophoziaceae', 'Lunulariaceae', 'Makinoaceae', 'Marchantiaceae', 'Mastigophoraceae', 'Meesiaceae', 'Mesoptychiaceae', 'Meteoriaceae', 'Metzgeriaceae', 'Microtheciellaceae', 'Mitteniaceae', 'Mizutaniaceae', 'Mniaceae', 'Monocarpaceae', 'Monocleaceae', 'Monosoleniaceae', 'Myriniaceae', 'Myuriaceae', 'Neckeraceae', 'Neotrichocoleaceae', 'Notothyladaceae', 'Octoblepharaceae', 'Oedipodiaceae', 'Orthorrhynchiaceae', 'Orthotrichaceae', 'Oxymitraceae', 'Pallaviciniaceae', 'Pelliaceae', 'Phyllodrepaniaceae', 'Phyllogoniaceae', 'Pilotrichaceae', 'Plagiochilaceae', 'Plagiotheciaceae', 'Pleurophascaceae', 'Pleuroziaceae', 'Pleuroziopsaceae', 'Polytrichaceae', 'Porellaceae', 'Pottiaceae', 'Prionodontaceae', 'Pseudoditrichaceae', 'Pseudolepicoleaceae', 'Pterigynandraceae', 'Pterobryaceae', 'Ptilidiaceae', 'Ptychomitriaceae', 'Ptychomniaceae', 'Racopilaceae', 'Radulaceae', 'Regmatodontaceae', 'Rhabdoweisiaceae', 'Rhachitheciaceae', 'Rhacocarpaceae', 'Rhizogoniaceae', 'Ricciaceae', 'Riellaceae', 'Rigodiaceae', 'Rutenbergiaceae', 'Scapaniaceae', 'Schistochilaceae', 'Schistostegaceae', 'Scorpidiaceae', 'Seligeriaceae', 'Sematophyllaceae', 'Serpotortellaceae', 'Sorapillaceae', 'Sphaerocarpaceae', 'Sphagnaceae', 'Spiridentaceae', 'Splachnaceae', 'Splachnobryaceae', 'Stereophyllaceae', 'Takakiaceae', 'Targioniaceae', 'Tetraphidaceae', 'Thamnobryaceae', 'Theliaceae', 'Thuidiaceae', 'Timmiaceae', 'Trachypodaceae', 'Treubiaceae', 'Trichocoleaceae', 'Trichotemnomataceae', 'Vandiemeniaceae', 'Vetaformaceae', 'Viridivelleraceae', 'Wardiaceae', 'Wiesnerellaceae']_50_50TIPO = 'A'_50ARRAYZAO = A_50_50arrayzin = []_50aaaarray = []_50csv_data = csv.reader(open('/home/hugo/Documents/GENERA/'+TIPO+'.csv'))_50header = next(csv_data)_50_50for row in csv_data:_50 arrayzin.append(row[0])_50 aaaarray.append(int(row[1]) - 1)_50_50_50class SpeciesSpider(scrapy.Spider):_50 name = 'species'_50 increment = 1_50 anotherIncrement = 1_50 start_urls = [_50 'http://www.theplantlist.org/1.1/browse/'+TIPO+'/'+ARRAYZAO[0]+'/'+arrayzin[0]]_50_50 def parse(self, response):_50 species = response.css('table.names td> a i.species')_50_50 for s in species:_50_50 yield {'name': s.css('::text').get(), 'genus_id': self.anotherIncrement}_50_50 self.anotherIncrement += 1_50_50 if (aaaarray[self.anotherIncrement - 1] != self.increment - 1):_50 self.increment += 1_50_50 yield scrapy.Request('http://www.theplantlist.org/1.1/browse/'+TIPO+'/'+ARRAYZAO[self.increment-1]+'/'+arrayzin[self.anotherIncrement-1])
Nesse aqui fiz até questão de ler um csv para obter os gêneros que eu já coletei, então é um uso mais avançado dessa ferramenta.
Como nos outros casos, o arquivo csv pode ser encontrado no meu §repositório
Como salvar o outup em um arquivo csv
Se vc tem alguma familiaridade com o terminal linux você vai entender instantaneamente esse código.
scrapy crawl <crawler> -o arquivo.csv -t csv
Você inicia o crawler, escolhendo ele através do nome dele que definimos na linha 9 do último exemplo, e escrevemos o output para o arquivo arquivo.csv.
Considerações finais
Bem, o que eu tinha para mostrar aqui era isso. Esse foi um projetinho muito legal de fazer; nunca imaginaria que teria que coletar tantos dados para meu objetivo principal, §Yggdrasil Project. Definitivamente foi uma forma bem prática de aprender scrapy e como utilizar esses dados para contruir um banco de dados.
Se você quiser o arquivo .sql do banco que criei com esses dados você pode acessar o repositório do Yggdrasil Projects, ele vai estar no root do projeto.