Maison >développement back-end >Tutoriel Python >Python explore les données de l'encyclopédie Baidu
Déterminer l'objectif : Déterminer quelle partie des données de quelles pages de quel site Web explorer. Cet exemple capture le titre et l'introduction de la page d'entrée Python de l'Encyclopédie Baidu et de la page d'entrée associée à Python.
Objectif de l'analyse : analyser le format de l'URL à crawler et limiter la portée du crawl. Analysez le format des données à capturer. Dans cet exemple, nous devons analyser le format des balises où se trouvent les deux données, titre et introduction. Analysez le format de l'encodage de la page à analyser. Dans la section Analyseur de page Web, vous devez spécifier l'encodage de la page Web avant de pouvoir effectuer une analyse correcte.
Écrire du code : dans la partie analyseur de page Web, vous devez utiliser les résultats obtenus en analysant la cible.
Exécuter le robot : effectuez la capture de données.
1. Format de l'URL
Entrez dans la page d'entrée Python de l'Encyclopédie Baidu Les liens vers les entrées associées sur la page sont relativement uniformes, pour la plupart /view/xxx.htm
.
2. Format des données
Le titre est situé dans la sous-balise h1 sous la classe lemmaWgt-lemmaTitle-title, et l'introduction est située sous la classe lemma-summary.
3. Format d'encodage
Affichez le format d'encodage de la page, qui est utf-8.
Après l'analyse ci-dessus, les résultats sont les suivants :
Dans sublime Next, créez un nouveau dossier baike-spider comme répertoire racine du projet.
Créez un nouveau spider_main.py en tant que planificateur principal du robot d'exploration.
Créez un nouveau url_manger.py en tant que gestionnaire d'URL.
Créez un nouveau html_downloader.py en tant que téléchargeur HTML.
Créez un nouveau html_parser.py comme analyseur HTML.
Créez un nouveau html_outputer.py comme outil d'écriture de données.
La structure finale du projet est la suivante :
# coding:utf-8 import url_manager, html_downloader, html_parser, html_outputer class SpiderMain(object): def __init__(self): self.urls = url_manager.UrlManager() self.downloader = html_downloader.HtmlDownloader() self.parser = html_parser.HtmlParser() self.outputer = html_outputer.HtmlOutputer() def craw(self, root_url): count = 1 self.urls.add_new_url(root_url) while self.urls.has_new_url(): try: new_url = self.urls.get_new_url() print('craw %d : %s' % (count, new_url)) html_cont = self.downloader.download(new_url) new_urls, new_data = self.parser.parse(new_url, html_cont) self.urls.add_new_urls(new_urls) self.outputer.collect_data(new_data) if count == 10: break count = count + 1 except: print('craw failed') self.outputer.output_html() if __name__=='__main__': root_url = 'http://baike.baidu.com/view/21087.htm' obj_spider = SpiderMain() obj_spider.craw(root_url)
# coding:utf-8 class UrlManager(object): def __init__(self): self.new_urls = set() self.old_urls = set() def add_new_url(self, url): if url is None: return if url not in self.new_urls and url not in self.old_urls: self.new_urls.add(url) def add_new_urls(self, urls): if urls is None or len(urls) == 0: return for url in urls: self.add_new_url(url) def has_new_url(self): return len(self.new_urls) != 0 def get_new_url(self): new_url = self.new_urls.pop() self.old_urls.add(new_url) return new_url
# coding:utf-8 import urllib.request class HtmlDownloader(object): def download(self, url): if url is None: return None response = urllib.request.urlopen(url) if response.getcode() != 200: return None return response.read()
# coding:utf-8 from bs4 import BeautifulSoup import re from urllib.parse import urljoin class HtmlParser(object): def _get_new_urls(self, page_url, soup): new_urls = set() # /view/123.htm links = soup.find_all('a', href=re.compile(r'/view/\d+\.htm')) for link in links: new_url = link['href'] new_full_url = urljoin(page_url, new_url) # print(new_full_url) new_urls.add(new_full_url) #print(new_urls) return new_urls def _get_new_data(self, page_url, soup): res_data = {} # url res_data['url'] = page_url # <dd class="lemmaWgt-lemmaTitle-title"> <h1>Python</h1> title_node = soup.find('dd', class_='lemmaWgt-lemmaTitle-title').find('h1') res_data['title'] = title_node.get_text() # <p class="lemma-summary" label-module="lemmaSummary"> summary_node = soup.find('p', class_='lemma-summary') res_data['summary'] = summary_node.get_text() # print(res_data) return res_data def parse(self, page_url, html_cont): if page_url is None or html_cont is None: return soup = BeautifulSoup(html_cont, 'html.parser') # print(soup.prettify()) new_urls = self._get_new_urls(page_url, soup) new_data = self._get_new_data(page_url, soup) # print('mark') return new_urls, new_data
# coding:utf-8 class HtmlOutputer(object): def __init__(self): self.datas = [] def collect_data(self, data): if data is None: return self.datas.append(data) def output_html(self): fout = open('output.html','w', encoding='utf-8') fout.write('<html>') fout.write('<body>') fout.write('<table>') for data in self.datas: fout.write('<tr>') fout.write('<td>%s</td>' % data['url']) fout.write('<td>%s</td>' % data['title']) fout.write('<td>%s</td>' % data['summary']) fout.write('</tr>') fout.write('</table>') fout.write('</body>') fout.write('</html>') fout.close()
Sur la ligne de commande, exécutez python spider_main.py
.
Description du problème : UnicodeEncodeError : le codec 'gbk' ne peut pas encoder le caractère 'xa0' en position...
Lors de l'écriture d'un fichier en utilisant Python, ou Lors de l'écriture de flux de données réseau dans des fichiers locaux, vous rencontrerez ce problème dans la plupart des cas. Il existe de nombreux articles similaires sur Internet expliquant comment résoudre ce problème, mais il ne s'agit que d'encodage et de décodage. Est-ce la véritable cause de ce problème ? Non. Plusieurs fois, nous utilisons le décodage et l'encodage, et essayons divers encodages, tels que utf8, utf-8, gbk, gb2312, etc. Nous avons essayé tous les encodages, mais l'erreur persiste, ce qui est frustrant.
Lors de l'écriture de scripts python sous Windows, le problème de codage est très grave. Lors de l'écriture de flux de données réseau dans des fichiers, nous rencontrerons plusieurs encodages :
1. #encoding='XXX'
L'encodage ici (c'est-à-dire le contenu de la première ligne du fichier python) fait référence au python. script L'encodage du fichier lui-même n'a pas d'importance. Tant que l'encodage de XXX et le fichier lui-même sont les mêmes, tout ira bien.
Par exemple, différents encodages peuvent être définis dans le menu "Format" du bloc-notes. Dans ce cas, vous devez vous assurer que l'encodage défini dans le menu est le même que l'encodage XXX. S'il est différent, une erreur se produira. être signalé.
2. Encodage du flux de données réseau
Par exemple, si vous obtenez une page Web, alors l'encodage du flux de données réseau est l'encodage de la page Web. Besoin d'utiliser le décodage pour décoder en codage Unicode.
3. Encodage du fichier cible
Écrire le flux de données réseau dans un nouveau fichier Le code d'écriture du fichier est le suivant :
fout = open('output.html','w') fout.write(str)
Sous Windows, l'encodage par défaut de. les nouveaux fichiers sont gbk , l'interpréteur python utilisera le codage gbk pour analyser notre flux de données réseau str. Cependant, str est décodé en codage Unicode, ce qui entraînera un échec d'analyse et les problèmes ci-dessus. La solution est de changer l'encodage du fichier cible :
fout = open('output.html','w', encoding='utf-8')
更多Python抓取百度百科数据 相关文章请关注PHP中文网!