Bonjour à tous, @_akisato.
Crawler / web scraping Calendrier de l'Avent http://qiita.com/advent-calendar/2015/ Il est écrit comme un article sur le 6ème jour du robot.
Aujourd'hui, je voudrais vous présenter le scraping des pages Web qui ne peuvent pas être lues à moins que JavaScript et les cookies ne soient autorisés.
L'implémentation est téléchargée sur GitHub https://github.com/akisato-/pyScraper.
(1) Obtenez la page Web avec les demandes, et (2) exécutez le scraping avec BeautufulSoup4. L'analyseur HTML standard Python n'est pas très bon, nous allons donc utiliser lxml ici. Pour l'utilisation de base de BeautifulSoup4, reportez-vous à http://qiita.com/itkr/items/513318a9b5b92bd56185.
Utilisez pip.
pip install requests
pip install lxml
pip install beautifulsoup4
Je pense que ce sera comme suit. Si vous spécifiez l'URL de la page que vous souhaitez gratter et le nom du fichier de sortie, le titre de la page sera renvoyé au format JSON. La fonction grattage est le corps principal.
scraping.py
import sys
import json
import requests
from bs4 import BeautifulSoup
import codecs
def scraping(url, output_name):
# get a HTML response
response = requests.get(url)
html = response.text.encode(response.encoding) # prevent encoding errors
# parse the response
soup = BeautifulSoup(html, "lxml")
# extract
## title
header = soup.find("head")
title = header.find("title").text
## description
description = header.find("meta", attrs={"name": "description"})
description_content = description.attrs['content'].text
# output
output = {"title": title, "description": description_content}
# write the output as a json file
with codecs.open(output_name, 'w', 'utf-8') as fout:
json.dump(output, fout, indent=4, sort_keys=True, ensure_ascii=False)
if __name__ == '__main__':
# arguments
argvs = sys.argv
## check
if len(argvs) != 3:
print("Usage: python scraping.py [url] [output]")
exit()
url = argvs[1]
output_name = argvs[2]
scraping(url, output_name)
Le nombre de pages Web qui ne peuvent pas être vues sans l'activation de JavaScript augmente considérablement. Si vous accédez à une telle page avec la source ci-dessus, vous n'obtiendrez que la page "Veuillez activer JavaScript".
Afin de prendre en charge de telles pages, nous remplacerons l'acquisition de page Web effectuée dans les demandes par une combinaison de Selenium et PhantomJS. Selenium est un outil pour automatiser les opérations du navigateur et PhantomJS est un navigateur basé sur Qt. [^ navigateur]
[^ browser]: PhantomJS est un navigateur, vous pouvez donc le remplacer par un navigateur Web couramment utilisé tel que IE, Firefox, Chrome, etc. Pour plus de détails, voir le document officiel http://docs.seleniumhq.org/docs/03_webdriver.jsp#selenium-webdriver-s-drivers.
Sur Mac et Linux, il peut être installé immédiatement avec un gestionnaire de paquets tel que brew ou yum.
Mac
brew install phantomjs
CentOS
yum install phantomjs
Sous Windows, téléchargez le binaire sur http://phantomjs.org/download.html, placez-le dans un emplacement approprié, puis placez-le dans le chemin.
Vous pouvez le faire immédiatement avec pip.
pip install selenium
En utilisant Selenium et PhantomJS, la source de grattage est modifiée comme suit. Il n'est pas nécessaire de modifier la procédure après l'acquisition de la page Web. Configurez le pilote Web PhantomJS avec Selenium et obtenez le code HTML via ce pilote. Après cela, c'est pareil. Si vous souhaitez enregistrer le journal des opérations du pilote, remplacez os.path.devnull par le nom du fichier.
scraping_js.py
import sys
import json
import os
import requests
from selenium import webdriver
from bs4 import BeautifulSoup
import codecs
def scraping(url, output_name):
# Selenium settings
driver = webdriver.PhantomJS(service_log_path=os.path.devnull)
# get a HTML response
driver.get(url)
html = driver.page_source.encode('utf-8') # more sophisticated methods may be available
# parse the response
soup = BeautifulSoup(html, "lxml")
# extract
## title
header = soup.find("head")
title = header.find("title").text
## description
description = header.find("meta", attrs={"name": "description"})
description_content = description.attrs['content'].text
# output
output = {"title": title, "description": description_content}
# write the output as a json file
with codecs.open(output_name, 'w', 'utf-8') as fout:
json.dump(output, fout, indent=4, sort_keys=True, ensure_ascii=False)
if __name__ == '__main__':
# arguments
argvs = sys.argv
## check
if len(argvs) != 3:
print("Usage: python scraping.py [url] [output]")
exit()
url = argvs[1]
output_name = argvs[2]
scraping(url, output_name)
Vous pouvez entrer le paramètre de proxy comme argument de PhantomJS.
phantomjs_args = [ '--proxy=proxy.server.no.basho:0000' ]
driver = webdriver.PhantomJS(service_args=phantomjs_args, service_log_path=os.path.devnull)
Les cookies sont activés par défaut dans PhantomJS. Si vous souhaitez conserver le fichier cookie à portée de main, vous pouvez le définir dans l'argument de PhantomJS.
phantomjs_args = [ '--cookie-file={}'.format("cookie.txt") ]
driver = webdriver.PhantomJS(service_args=phantomjs_args, service_log_path=os.path.devnull)
Si toutes les fonctions sont couvertes, ce sera comme suit.
scraping_complete.py
import sys
import json
import os
import requests
from selenium import webdriver
from bs4 import BeautifulSoup
import codecs
def scraping(url, output_name):
# Selenium settings
phantomjs_args = [ '--proxy=proxy.server.no.basho:0000', '--cookie-file={}'.format("cookie.txt") ]
driver = webdriver.PhantomJS(service_args=phantomjs_args, service_log_path=os.path.devnull)
# get a HTML response
driver.get(url)
html = driver.page_source.encode('utf-8') # more sophisticated methods may be available
# parse the response
soup = BeautifulSoup(html, "lxml")
# extract
## title
header = soup.find("head")
title = header.find("title").text
## description
description = header.find("meta", attrs={"name": "description"})
description_content = description.attrs['content']
# output
output = {"title": title, "description": description_content}
# write the output as a json file
with codecs.open(output_name, 'w', 'utf-8') as fout:
json.dump(output, fout, indent=4, sort_keys=True, ensure_ascii=False)
if __name__ == '__main__':
# arguments
argvs = sys.argv
## check
if len(argvs) != 3:
print("Usage: python scraping.py [url] [output]")
exit()
url = argvs[1]
output_name = argvs[2]
scraping(url, output_name)
Recommended Posts