代碼覺得沒問題??!就是沒有結(jié)果,console和html文件都是空白!求助!
#調(diào)度程序
#抓取百度百科相關(guān)Python詞條網(wǎng)頁的標(biāo)題和簡介
from baike_spider import url_manager, html_downloader, html_parser,\
? ? html_outputer
#創(chuàng)建類?
class SpiderMain(object):
? ??
? ? #構(gòu)造函數(shù) 初始化
? ? def __init__(self):
? ? ? ? #實(shí)例化需引用的對象
? ? ? ? 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):
? ? ? ? #添加一個(gè)到url中
? ? ? ??
? ? ? ? self.urls.add_new_url(root_url)
? ? ? ??
? ? ? ??
? ? ? ? #無法執(zhí)行????
? ? ? ? while self.urls.has_new_url():
? ? ? ? ? ? #異常處理
? ? ? ? ? ?
? ? ? ? ? ? try:
? ? ? ? ? ? ? ? #打印1000條
? ? ? ? ? ? ? ? count = 1
? ? ? ? ? ? ? ? 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)
? ? ? ? ? ? ? ??
? ? ? ? ? ? ? ? #爬一千個(gè)界面
? ? ? ? ? ? ? ? if count == 1000:
? ? ? ? ? ? ? ? ? ? break
? ? ? ? ? ? ? ? count = count + 1
? ? ? ? ? ? except:
? ? ? ? ? ? ? ? print("craw failed")
? ? ? ? self.outputer.output_html()
? ? ? ? ? ??
#創(chuàng)建main方法
if __name__ == "__main__":?
? ? root_url = "https://baike.baidu.com/item/Python/407313"
? ? obj_spider = SpiderMain()
? ? obj_spider.craw(root_url)
? ??
? ??
class UrlManager(object):
? ? 'url管理類'??
? ? #構(gòu)造函數(shù)初始化set集合
? ? def __init__(self):
? ? ? ? self.new_urls = set()#待爬取的url?
? ? ? ? self.old_urls = set()#已爬取的url
? ??
? ? #向管理器中添加一個(gè)新的url
? ? def add_new_url(self, url):
? ? ? ? if url is None:
? ? ? ? ? ? return
? ? ? ??
? ? ? ? if url not in self.new_urls and self.old_urls:
? ? ? ? ? ? #既不在待爬取的url也不在已爬取的url中,是一個(gè)全新的url,
? ? ? ? ? ? #因此將其添加到new_urls?
? ? ? ? ? ? self.new_urls.add(url)
? ??
? ? # 向管理器中添加批量新的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)#調(diào)用add_new_url()
? ??
? ? #判斷是否有新的待爬取的url
? ? def has_new_url(self):
? ? ? ? return len(self.new_urls) == 1
? ??
? ? #獲取一個(gè)待爬取的url
? ? def get_new_url(self):
? ? ? ? new_url = self.new_urls.pop()#默認(rèn)移除最后一個(gè)元素
? ? ? ? self.old_urls.add(new_url)
? ? ? ? return new_url
? ??
? ??
import urllib
class HtmlDownloader(object):
? ??
? ? '下載頁面內(nèi)容'? ??
? ? def download(self, url):
? ? ? ? if url is None:
? ? ? ? ? ? return None
? ? ? ? response = urllib.request.urlopen(url)
? ? ? ? if response.getcode() != 200:
? ? ? ? ? ? return None
? ? ? ? return response.read()
? ??
? ? ? ? ?
? ? ? ? '''
? ? ? ? #解決請求路徑中含義中文或特殊字符??
? ? ? ? url_ = quote(new_url, safe=string.printable);??
? ? ? ? response = request.urlopen(url_)??
? ? ? ? if(response.getcode()!=200):??
? ? ? ? ? ? return None #請求失敗??
? ? ? ? html = response.read()??
? ? ? ? return html.decode("utf8")
? ? ? ? '''
from bs4 import BeautifulSoup
import re
import urllib
class HtmlParser(object):
? ??
? ? #page_url 基本url 需拼接部分
? ? def _get_new_urls(self, page_url, soup):
? ? ? ? new_urls = set()
? ? ? ??
? ? ? ? #https://baike.baidu.com/item/Python/407313
? ? ? ? #匹配/item/Python/407313
? ? ? ? links = soup.find_all('a', href = re.compile(r"/item/*"))
? ? ? ? for link in links:
? ? ? ? ? ? new_url = link['href']
? ? ? ? ? ? #例如page_url=http://baike.baidu.com/item/Python new_url=/item/史記·2016?fr=navbar??
? ? ? ? ? ? #則使用parse.urljoin(page_url,new_url)后 new_full_url = http://baike.baidu.com/item/史記·2016?fr=navbar
? ? ? ? ? ? new_full_url = urllib.parse.urljoin(page_url, new_url)
? ? ? ? ? ? new_urls.add(new_full_url)
? ? ? ? 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') #獲取標(biāo)題內(nèi)容
? ? ? ? res_data['title'] = title_node.get_text()
? ? ? ??
? ? ? ? #<div class="lemma-summary" label-module="lemmaSummary">
? ? ? ? summary_node = soup.find('div', class_="lemma-summary") #獲取簡介內(nèi)容
? ? ? ? res_data['summary'] = summary_node.get_text()
? ? ? ??
? ? ? ? return res_data
? ??
? ? #new_url路徑 html_context界面內(nèi)容
? ? def parse(self, page_url, html_cont):
? ? ? ? if page_url is None or html_cont is None:
? ? ? ? ? ? return
? ? ? ? #python3缺省的編碼是unicode, 再在from_encoding設(shè)置為utf8, 會被忽視掉,
? ? ? ? #去掉【from_encoding = "utf-8"】這一個(gè)好了
? ? ? ? #soup = BeautifulSoup(html_cont, 'html.parse', from_encoding="utf-8")
? ? ? ? soup = BeautifulSoup(html_cont, 'html.parser')
? ? ? ? new_urls = self._get_new_urls(page_url, soup)
? ? ? ? new_data = self._get_new_data(page_url, soup)
? ? ? ? return new_urls,new_data
class HtmlOutputer(object):
? ??
? ? def __init__(self):
? ? ? ? self.datas = []#存放搜集的數(shù)據(jù)
? ??
? ? def collect_data(self, data):
? ? ? ? if data is None:
? ? ? ? ? ? return
? ? ? ? self.datas.append(data)
? ??
? ? def output_html(self):
? ? ? ? fout = open('output.html', 'w', encoding='utf8')#寫入文件 防止中文亂碼
? ? ? ? fout.write('<html>\n')
? ? ? ? fout.write('<body>\n')
? ? ? ? fout.write('<table>\n')
? ? ? ??
? ? ? ? #ascii
? ? ? ? for data in self.datas:
? ? ? ? ? ? fout.write('<tr>\n')
? ? ? ? ? ? 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>\n')
? ? ? ? fout.write('</body>\n')
? ? ? ? fout.write('</html>\n')
? ? ? ??
? ? ? ? fout.close()
2019-02-18
打斷點(diǎn) 看看到哪出問題了