-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdata_scraping.py
139 lines (97 loc) · 6.75 KB
/
data_scraping.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# -*- coding: utf-8 -*-
"""data_scraping.ipynb
Automatically generated by Colaboratory.
Original file is located at
https://colab.research.google.com/drive/1juLtmnOi741mtmUGFqPc1v0BhK6IuXJL
Data scraping é a utilização de códigos que simulam as requisições de um navegador web, para obter dados de sites; lendo, processando e selecionando seu conteúdo.
O data scraping pode ter vários objetivos:
* Obter dados de mercado para tomada de decisão em empresas.
* Obter dados para treinamento de inteligência artificial.
* Obter para uso em um modelo de negócios.
* Obter dados para pesquisa científica.
* etc...
A legalidade do data scraping é complexa, podendo resultar em atividade ilegal se as condições corretas do seu uso não forem observadas. Entre as questões legais podemos observar:
* O site pode proibir em seus termos de usa a utilização de data scraping.
* O data scraping e a utilização dos dados obtidos, pode estar em desacordo com legislações de proteção de dados, como da União Européia e do Brasil, por exemplo. Um exemplo seria a exposição de dados pessoais de susários.
* A utilização de dados via data scraping de entidades públicas, como portal da transparência, também podem depender de condições legais e éticas, especialmente quando usado por empresas privadas para obter lucro.
Portanto o para fazer o data scraping é necessário verificar duas condilções importantes:
* 1) Se a utilização de data scraping é permitida pelo site e não fere nenhuma legislação.
* 2) Se a utilização dos dados obtidos com data scraping não fere a legislação e os termos de uso do site.
Além disso, existem considerações de possíveis danos que podem ser causados. Muitas requisições para um mesmo site podem sobrecarregar o servidor, inclusive parando o seu serviço, o que pode caracterizar um atque DoS (Denial of Service [negação de serviço]). Que pode ter consequências legais e cíveis.
Portanto, nunca deve ser feito data scraping sem considerações as questões legias, éticas e de segurança.
Uma discussão sobre esses aspectos pode ser vista no artigo:
https://www.migalhas.com.br/coluna/dados-publicos/378258/os-desafios-juridicos-do-web-scraping
Para os exemplos a seguir, será utilizado como base o tutorial:
https://realpython.com/python-web-scraping-practical-introduction/
que disponibiliza um site específico para ser acessado no tutorial.
A biblioteca urllib será utilizada para fazer as requisições web e ler os dados.
"""
from urllib.request import urlopen
"""Para requisitar um url (endereço do site), temos que definir o endereço como uma string."""
url = "http://olympus.realpython.org/profiles/aphrodite"
"""Com o comando open abrimos a url e criamos um objeto a partir do qual poderemos solicitar dados."""
page = urlopen(url)
"""A seguir podemos ler os dados do endereço com o comando com o comando read(). Os dados retornados são uma sequância de bytes, que precisam ser decodificados em um texto, informando qual a codificação, nesse caso utf-8"""
html_bytes = page.read()
html = html_bytes.decode("utf-8")
print(html)
"""Como o resultado retornado é uma string (texto), os comandos do python para trabalhar com string podem ser usados para processar e selecionar esses dados. No exemplo abaixo vamos usar o find() para encontrar o local de um texto, e depois usaremos slicing (definir índices entre colchetes para selecionar o trecho de texto que queremos)."""
#identifica onde está o tag <title> que indica o título
indice_tag = html.find("<title>")
#calcula onde começa o texto do título somando o indice da tag com o comprimento da tag
inicio = indice_tag + len("<title>")
#identifica onde fica a tag de fechamento do título
fim = html.find("</title>")
#com o slicing, seleciona o texto do título:
titulo=html[inicio:fim]
print(titulo)
"""Vamos agora testar esse mesmo código em um outro site:"""
url = "http://olympus.realpython.org/profiles/poseidon"
page = urlopen(url)
html_bytes = page.read()
html = html_bytes.decode("utf-8")
#identifica onde está o tag <title> que indica o título
indice_tag = html.find("<title>")
#calcula onde começa o texto do título somando o indice da tag com o comprimento da tag
inicio = indice_tag + len("<title>")
#identifica onde fica a tag de fechamento do título
fim = html.find("</title>")
#com o slicing, seleciona o texto do título:
titulo=html[inicio:fim]
print(titulo)
"""Nesse caso o código não funcionou tão bem, pois vieram tags html junto com o texto do título. O motivo é que existe um espaço a mais na tag <title >, que faz com que retorne -1 (não encontrado), somando o o tamanho de title, resulta em um íncice no início do html, antes da tag title.
Um forma bem poderosa de processar strings no python é com expressões regulares. Existe uma bilbioteca chamada re que permite trabalhar com expressões regulares.
"""
import re #biblioteca de expressões regulares
"""Expressões rebulares usam caracters especiais para determinar uma regra lógica da composição da string. Por exemplo, o \* define que a string pode ter 0 ou mais ocorrências do caracter logo antes do \*.
No exemplo abaixo o comando findall verifica se encontra a expressão regular (primeiro parâmetro), no texto (segundo parâmetro). A expressão regular ab*c diz que o texto tem que inciar com "a", pode ter 0 ou mais ocorrências do "b" e deve terminar com "c".
"""
re.findall("ab*c", "ac abc abbc bca")
"""Expressões reculares diferenciam maiúsculas. Para não diferenciar use:"""
re.findall("ab*c", "ABC", re.IGNORECASE)
"""O "." é um caracter coringa. A expressão .* significa que a empressão pode ter qualquer caracter repetido 0 ou mais vezes naquela posição."""
print(re.findall("a.*c", "ac"))
print(re.findall("a.*c", "abbc"))
print(re.findall("a.*c", "a c"))
print(re.findall("a.*c", "amlc"))
print(re.findall("a.*c", "kmlc"))
"""O comando sub substitui ocorrências de uma expressão regular por uma palavra"""
string = "Everything is <replaced> if it's in <tags>."
string = re.sub("<.*>", "ELEPHANTS", string)
string
"""Para substituir tags na menor ocorrência, ou seja, são considerar uma tag que engloba várias tags. podemos usar o símbolo "?"
"""
string = "Everything is <replaced> if it's in <tags>."
string = re.sub("<.*?>", "ELEPHANTS", string)
string
"""Portanto, podemos usar agora expressões regulares para encontrar textos de forma mais eficiente e considerando coisas como possíveis espaços dentro das tags"""
import re
from urllib.request import urlopen
url = "http://olympus.realpython.org/profiles/poseidon"
page = urlopen(url)
html = page.read().decode("utf-8")
pattern = "<title.*?>.*?</title.*?>"
match_results = re.search(pattern, html, re.IGNORECASE)
title = match_results.group()
title = re.sub("<.*?>", "", title) # Remove HTML tags
print(title)