网络爬虫Python试验
網(wǎng)絡(luò)爬蟲
這次去杭州參加阿里巴巴的離線大數(shù)據(jù)處理暑期課,得到一個(gè)思路。
之前一直糾結(jié)于沒有數(shù)據(jù)要怎么訓(xùn)練我的旅行個(gè)性化推薦。畢設(shè)木有頭緒啊,做不粗來要人命呀!
現(xiàn)在覺得可以在網(wǎng)上爬一些數(shù)據(jù)下來,看看能不能分析出各個(gè)景點(diǎn)之間的關(guān)系。
現(xiàn)在 開貼記錄自己的工作。
?2013.7.24
使用urllib。(3.0以后urllib2就整合到urllib中了,見【這里】)
import urllib.request c = urllib.request.urlopen('http://www.baidu.com') contents = c.read() print(contents[0:50])代碼參考自《集體智慧編程》,然后根據(jù)python3.2做了一些改動(dòng)。
可以看到爬下來的一些東西
除了爬蟲以外,我們還需要HTML和XML的解析器。
http://www.crummy.com/software/BeautifulSoup/bs4/doc/
安裝好以后,我們?cè)囈幌耣eautiful soup 4
?現(xiàn)在安裝一下python和mysql的連接器。地址見?http://dev.mysql.com/downloads/connector/python/
鏈接數(shù)據(jù)庫(kù)的方法見?http://smilejay.com/2013/03/python3-mysql-connector/
?過濾字母和數(shù)字
之前的構(gòu)想是打算濾掉字母、數(shù)字、空白標(biāo)示符、HTML標(biāo)簽,只留下中文字符和最基本的標(biāo)點(diǎn)符號(hào)。今早醒來想一想,覺得這樣不行,因?yàn)闉V掉的這些部分其實(shí)含有豐富的信息。比如a標(biāo)簽的路徑和內(nèi)容都是文章與其他網(wǎng)頁(yè)的重要關(guān)聯(lián)。h標(biāo)簽和em標(biāo)簽也是同理。而且css部分,看似無用,其實(shí)可以用來判斷這個(gè)站點(diǎn)是否夠新鮮(通過它使用的css技術(shù),例如是否使用了自適應(yīng)、聲明的doc類型是否夠潮。當(dāng)然,站點(diǎn)的新鮮程度與內(nèi)容的重要程度是不太有關(guān)系的)。總之,今天需要做一些改動(dòng),把完整的網(wǎng)頁(yè)信息保存下來,而不是只保存文本的部分。以后要用到哪些,再拿來分析和提取。
————————————————————
2013.7.26?代碼備份
#2013-7-26 import mysql.connector import sys, os from bs4 import BeautifulSoup from urllib.request import urlopen from html.parser import HTMLParser import re#數(shù)據(jù)庫(kù)相關(guān)操作 class DBconnector:user = 'root'pwd = 'root'host = '127.0.0.1'db = 'test'cnx = mysql.connector.connect(user=user, password=pwd, host=host, database=db)cursor = cnx.cursor()def __init__(self):passdef __del__(self):self.cursor.close()self.cnx.close()def createTable():create_table_sql = "CREATE TABLE IF NOT EXISTS testpages ( \url varchar(100) , \title varchar(50), content varchar(10000) ) \CHARACTER SET utf8"try:self.cursor.execute(create_table_sql)except mysql.connector.Error as err:print("create table 'pages' failed.")print("Error: {}".format(err.msg))sys.exit()self.cnx.commit()def insert(self,url, title, content):sql = "REPLACE INTO pages (url, title, content) VALUES ('{}', '{}', '{}')".format(url, title, content)try:self.cursor.execute(sql)except mysql.connector.Error as err:print("replace into table 'pages' - failed.")print("Error: {}".format(err.msg))sys.exit()self.cnx.commit()#從html中刪去標(biāo)簽 class MLStripper(HTMLParser):def __init__(self):super().__init__()self.reset()self.fed = []def handle_data(self, d):self.fed.append(d)def get_data(self):return ''.join(self.fed)def strip_tags(html):s = MLStripper()s.feed(html)return s.get_data()class Crawler:initURL = "http://lvyou.baidu.com/"conn = DBconnector()def webCapture(self):c = urlopen(self.initURL).read()c1 = "你好啊fdfdafd123456,.fdle)("soup = BeautifulSoup(c)links = soup('a')links.append(self.initURL)for link in links:c_temp = urlopen(link.href).read()print(link.href)soup = BeautifulSoup(c_temp)temp_links = soup('a')links += temp_linkstemplate = re.compile(r'\d|[a-z]|[A-Z]|\\|\/|<.*>|{|}|\s|-|#|"|\'')#body = template.sub('',strip_tags(c))body = template.sub('',str(soup.body))print(body)self.conn.insert(link, soup('title'), body)crawler = Crawler() crawler.webCapture()————————————————————
2013.7.27
今天更新了一些代碼
#20130727 import mysql.connector import sys, os from bs4 import BeautifulSoup from urllib.request import urlopen from html.parser import HTMLParser import re import hashlib#數(shù)據(jù)庫(kù)相關(guān)操作 class DBconnector:user = 'root'pwd = 'root'host = '127.0.0.1'db = 'test'cnx = mysql.connector.connect(user=user, password=pwd, host=host, database=db)cursor = cnx.cursor()def __init__(self):passdef __del__(self):self.cursor.close()self.cnx.close()def createTable():create_table_sql = "CREATE TABLE IF NOT EXISTS testpages ( \url varchar(100) , \title varchar(50), content varchar(10000) ) \CHARACTER SET utf8"try:self.cursor.execute(create_table_sql)except mysql.connector.Error as err:print("create table 'pages' failed.")print("Error: {}".format(err.msg))sys.exit()self.cnx.commit()def insert(self,url, title, content):sql = "REPLACE INTO pages (url, title, content) VALUES ('{}', '{}', '{}')".format(url, title, content)try:self.cursor.execute(sql)except mysql.connector.Error as err:print("replace into table 'pages' - failed.")print("Error: {}".format(err.msg))sys.exit()self.cnx.commit()def select(self, url):select_sql = "select content from pages where url ='{}'".format(url)try:self.cursor.execute(select_sql)for content in self.cursor:return contentexcept mysql.connector.Error as err:print("query table 'mytable' failed.")print("Error: {}".format(err.msg))sys.exit()#從html中刪去標(biāo)簽 class MLStripper(HTMLParser):def __init__(self):super().__init__()self.reset()self.fed = []def handle_data(self, d):self.fed.append(d)def get_data(self):return ''.join(self.fed)def strip_tags(html):s = MLStripper()s.feed(html)return s.get_data()class Crawler:conn = DBconnector()#判斷一個(gè)頁(yè)面是否已經(jīng)爬過def pageExist(self, url):charge = self.conn.select(url)print('---charge---',charge)if charge:return Trueelse:return False#將頁(yè)面內(nèi)容寫入文件中,以u(píng)rl的sha256命名,并返回文件名def writeToFile(self, url, content):location = 'G:\\pages\\'m = hashlib.sha256()m.update(url.encode('utf-8'))f = open(location + m.hexdigest(),'wb')f.write(content)f.closeprint('writing file: ' + url)return m.hexdigest()#將路徑、網(wǎng)頁(yè)標(biāo)題、文件名存入數(shù)據(jù)庫(kù)中def writeToDB(self, conn, url, title, filename):self.conn.insert(url, title, filename)#解析網(wǎng)頁(yè),分析出標(biāo)題、鏈接、內(nèi)容,并返回def parsePage(self, url):content = urlopen(url,timeout=5000).read()soup = BeautifulSoup(content)links = []tempLinks = [soup.a['href'],]print('--tempLinks--',tempLinks)for tempLink in tempLinks:if self.pageExist(tempLink):continueelse:#判斷是否是一條完整的路徑print('tempLink->' + tempLink)protocol = re.findall(r'http|https',tempLink)if len(protocol) == 0:print('none protocal has found')#從8開始找是因?yàn)閔ttps://的最后一個(gè)/剛好在第七位end = url.find('/',8)domain = url[0:end + 1]tempURL = ''.join(domain + tempLink)else:tempURL = tempLinkprint('tempURL->' + tempURL)links += [''.join(tempURL),]title = soup.titlereturn (title, links, content)def webCapture(self):links = ['http://www.cnblogs.com',]#"http://xian.cncn.com/"for link in links:print("current link->" + link)#解析頁(yè)面(title, addlinks, content) = self.parsePage(link)links += addlinks#將頁(yè)面內(nèi)容寫入文件filename = self.writeToFile(link, content)#將url、標(biāo)題、頁(yè)面對(duì)應(yīng)的文件名寫入數(shù)據(jù)庫(kù)中 self.writeToDB(self.conn, link, title, filename)crawler = Crawler() crawler.webCapture()————————————————————
2013.7.29
今天的爬蟲,因?yàn)榫幋a的原因整得人焦頭爛額
1、URL open timeout 是一種常態(tài),一定要寫try catch來處理這種情況,不能讓爬蟲因?yàn)殒溄映瑫r(shí)而退出
2、urllib的urlopen貌似只接受ascii型的參數(shù),查了半天也沒找到什么好辦法, 最后還是進(jìn)python33/lib/http/下面改了
client.py文件的953行
request.encode('ascii')為request.encode('utf-8')才終于跑起來了……
今天更新的代碼:(PS:晚上待著實(shí)驗(yàn)室真是一種喂蚊子的節(jié)奏……T_T)
#2013.7.29 import mysql.connector import sys, os from bs4 import BeautifulSoup import urllib from urllib.request import urlopen from html.parser import HTMLParser import re import hashlib import socket import imp#數(shù)據(jù)庫(kù)相關(guān)操作 class DBconnector:user = 'root'pwd = 'root'host = '127.0.0.1'db = 'test'cnx = mysql.connector.connect(user=user, password=pwd, host=host, database=db)cursor = cnx.cursor()def __init__(self):passdef __del__(self):self.cursor.close()self.cnx.close()def createTable():create_table_sql = "CREATE TABLE IF NOT EXISTS testpages ( \url varchar(100) , \title varchar(50), content varchar(10000) ) \CHARACTER SET utf8"try:self.cursor.execute(create_table_sql)except mysql.connector.Error as err:print("create table 'pages' failed.")print("Error: {}".format(err.msg))sys.exit()self.cnx.commit()def insert(self,url, title, content):sql = "REPLACE INTO pages (url, title, content) VALUES ('{}', '{}', '{}')".format(url, title, content)try:self.cursor.execute(sql)except mysql.connector.Error as err:print("replace into table 'pages' - failed.")print("Error: {}".format(err.msg))sys.exit()self.cnx.commit()def select(self, url):select_sql = "select content from pages where url ='{}'".format(url)try:self.cursor.execute(select_sql)for content in self.cursor:return contentexcept mysql.connector.Error as err:print("query table 'mytable' failed.")print("Error: {}".format(err.msg))sys.exit()#從html中刪去標(biāo)簽 class MLStripper(HTMLParser):def __init__(self):super().__init__()self.reset()self.fed = []def handle_data(self, d):self.fed.append(d)def get_data(self):return ''.join(self.fed)def strip_tags(html):s = MLStripper()s.feed(html)return s.get_data()class Crawler:conn = DBconnector()#判斷一個(gè)頁(yè)面是否已經(jīng)爬過def pageExist(self, url):charge = self.conn.select(url)if charge:return Trueelse:return False#將頁(yè)面內(nèi)容寫入文件中,以u(píng)rl的sha256命名,并返回文件名def writeToFile(self, url, content):location = 'G:\\pages\\'m = hashlib.sha256()m.update(url.encode('utf-8'))f = open(location + m.hexdigest(),'wb')f.write(content)f.closeprint('writing file: ' + m.hexdigest())return m.hexdigest()#將路徑、網(wǎng)頁(yè)標(biāo)題、文件名存入數(shù)據(jù)庫(kù)中def writeToDB(self, conn, url, title, filename):self.conn.insert(url, title, filename)#解析網(wǎng)頁(yè),分析出標(biāo)題、鏈接、內(nèi)容,并返回def parsePage(self, url):socket.setdefaulttimeout(2)try:content = urlopen(url).read()except urllib.error.URLError:print('URL open time out!')return None, None, Noneexcept socket.timeout:print('socket time out!')return None, None, Nonesoup = BeautifulSoup(content)links = []tempLinks = []atags = soup.findAll('a', attrs={'href': re.compile("^http://|https://")})print('len of atags->', len(atags))#從a標(biāo)簽中提取出路徑放入tempLinks中for atag in atags:tsoup = BeautifulSoup(str(atag))turl = tsoup.a['href']if turl in tempLinks:continueelse:tempLinks += [turl]for tempLink in tempLinks:if self.pageExist(tempLink):continueelse:#判斷是否是一條完整的路徑#print('tempLink->' + tempLink)protocol = re.findall(r'http|https',tempLink)if len(protocol) == 0:#從8開始找是因?yàn)閔ttps://的最后一個(gè)/剛好在第七位end = url.find('/',8)domain = url[0:end + 1]tempURL = ''.join(domain + tempLink)else:tempURL = tempLinklinks += [''.join(tempURL),]title = soup.titlereturn (title, links, content)def webCapture(self):links = ['http://lvyou.baidu.com/xian',]#"http://xian.cncn.com/"for link in links:#print("current link->" + link)#解析頁(yè)面(title, addlinks, content) = self.parsePage(link)if title == None and addlinks == None and content == None:continueelse:links += addlinks#將頁(yè)面內(nèi)容寫入文件filename = self.writeToFile(link, content)#將url、標(biāo)題、頁(yè)面對(duì)應(yīng)的文件名寫入數(shù)據(jù)庫(kù)中temp = re.compile(r'<.*>')title = temp.sub('',str(title))self.writeToDB(self.conn, link, title, filename)crawler = Crawler() crawler.webCapture()————————————————————
2013.7.31
今天重寫了links循環(huán)的部分,抓網(wǎng)頁(yè)的量也上去了。不過抽查一部分抓到的網(wǎng)頁(yè)發(fā)現(xiàn),基本上全被ajax占領(lǐng)了。最后紀(jì)念一下這些天的代碼。明天改用Scrapy框架來抓。
#20130731 import mysql.connector import sys, os from bs4 import BeautifulSoup import urllib from urllib.request import urlopen from html.parser import HTMLParser import re import hashlib import socket import imp#數(shù)據(jù)庫(kù)相關(guān)操作 class DBconnector:user = 'root'pwd = 'root'host = '127.0.0.1'db = 'test'cnx = mysql.connector.connect(user=user, password=pwd, host=host, database=db)cursor = cnx.cursor()def __init__(self):passdef __del__(self):self.cursor.close()self.cnx.close()def createTable():create_table_sql = "CREATE TABLE IF NOT EXISTS testpages ( \url varchar(100) , \title varchar(50), filename varchar(64) ) \CHARACTER SET utf8"try:self.cursor.execute(create_table_sql)except mysql.connector.Error as err:print("create table 'pages' failed.")print("Error: {}".format(err.msg))sys.exit()self.cnx.commit()def insert(self,url, title, filename):sql = "REPLACE INTO pages (url, title, filename) VALUES ('{}', '{}', '{}')".format(url, title, filename)try:self.cursor.execute(sql)except mysql.connector.Error as err:print("replace into table 'pages' - failed.")print("Error: {}".format(err.msg))sys.exit()self.cnx.commit()def select(self, url):select_sql = "select filename from pages where url ='{}'".format(url)try:self.cursor.execute(select_sql)for filename in self.cursor:return filenameexcept mysql.connector.Error as err:print("query table 'pages' failed.")print("Error: {}".format(err.msg))sys.exit()#從html中刪去標(biāo)簽 class MLStripper(HTMLParser):def __init__(self):super().__init__()self.reset()self.fed = []def handle_data(self, d):self.fed.append(d)def get_data(self):return ''.join(self.fed)def strip_tags(html):s = MLStripper()s.feed(html)return s.get_data()class Crawler:conn = DBconnector()#判斷一個(gè)頁(yè)面是否已經(jīng)爬過def pageExist(self, url):charge = self.conn.select(url)if charge:return Trueelse:return False#將頁(yè)面內(nèi)容寫入文件中,以u(píng)rl的sha256命名,并返回文件名def writeToFile(self, url, filename):location = 'G:\\pages\\'m = hashlib.sha256()m.update(url.encode('utf-8'))f = open(location + m.hexdigest(),'wb')f.write(filename)f.closeprint('writing file: ' + m.hexdigest())return m.hexdigest()#將路徑、網(wǎng)頁(yè)標(biāo)題、文件名存入數(shù)據(jù)庫(kù)中def writeToDB(self, conn, url, title, filename):self.conn.insert(url, title, filename)#解析網(wǎng)頁(yè),分析出標(biāo)題、鏈接、內(nèi)容,并返回def parsePage(self, url):socket.setdefaulttimeout(2)try:content = urlopen(url).read()except urllib.error.URLError:print('URL open time out!')return None, None, Noneexcept socket.timeout:print('socket time out!')return None, None, Noneexcept ConnectionAbortedError:print('socket time out!')return None, None, Nonesoup = BeautifulSoup(content)links = []tempLinks = []atags = soup.findAll('a', attrs={'href': re.compile("^http://|https://")})print('len of atags->', len(atags))#從a標(biāo)簽中提取出路徑放入tempLinks中for atag in atags:tsoup = BeautifulSoup(str(atag))turl = tsoup.a['href']if turl in tempLinks:continueelse:tempLinks += [turl]while len(tempLinks) != 0:tempLink = tempLinks.pop()if self.pageExist(tempLink):continueelse:#判斷是否是一條完整的路徑#print('tempLink->' + tempLink)protocol = re.findall(r'http|https',tempLink)if len(protocol) == 0:#從8開始找是因?yàn)閔ttps://的最后一個(gè)/剛好在第七位end = url.find('/',8)domain = url[0:end + 1]tempURL = ''.join(domain + tempLink)else:tempURL = tempLinklinks += [''.join(tempURL),]title = soup.titlereturn (title, links, content)def webCapture(self):links = ['http://lvyou.baidu.com/search?word=%E8%A5%BF%E5%AE%89&type=1']#"http://xian.cncn.com/"while len(links) != 0:link = links[0]print('links array length:',len(links))addlinks = self.handlePage(link)del links[0]if addlinks != None:links += addlinksdef handlePage(self,link):(title, addlinks, content) = self.parsePage(link)if title == None and addlinks == None and content == None:return Noneelse:#將頁(yè)面內(nèi)容寫入文件filename = self.writeToFile(link, content)#將url、標(biāo)題、頁(yè)面對(duì)應(yīng)的文件名寫入數(shù)據(jù)庫(kù)中temp = re.compile(r'<.*>')title = temp.sub('',str(title))self.writeToDB(self.conn, link, '', filename)return addlinkscrawler = Crawler() crawler.webCapture()現(xiàn)在爬蟲的帶處理網(wǎng)頁(yè)list有鏈接7W多條
之前最高有大到26W。不過爬到的質(zhì)量太差,有很多被掛馬的、廣告的,還有很頭疼的ajax的。哎,有點(diǎn)傷感。還是用框架吧。時(shí)間來不及精雕細(xì)琢一個(gè)自己的爬蟲了。
?——————————————
2013.08.01
今天換上scrapy。 方式參考其官網(wǎng)。
發(fā)現(xiàn)scrapy是不能自動(dòng)解析ajax的。還需要一個(gè)模擬人類操作的東東。叫selenium RC。安裝和測(cè)試的方式見 oscarxie的博客 http://www.cnblogs.com/oscarxie/archive/2008/07/20/1247004.html
【這邊】還有老外?wynbennett?寫的一段爬帶有js代碼網(wǎng)頁(yè)的代碼。
?
?——————————————
2013.08.02
?selenium RC python下的【手冊(cè)】
_______________________
2013.8.3
今天的代碼,完全跟以前不一樣了。selenium真是一個(gè)深藏功與名的爬蟲利器啊。
# -*- coding: utf-8 -*- from selenium import webdriver from selenium.webdriver.common.keys import Keys import hashlib import randomclass ScrapyPages:#網(wǎng)頁(yè)內(nèi)容保存目錄contentDir = "G:\\pages\\"#網(wǎng)頁(yè)鏈接保存目錄atagsDir = "G:\\atags\\"#保存網(wǎng)頁(yè)與文件名對(duì)應(yīng)關(guān)系的文件mappingFile = "G:\\mapping"#已處理的鏈接handledLinks = []#待處理的鏈接unhandledLinks = []#打開瀏覽器驅(qū)動(dòng),默認(rèn)為火狐def openPage(self, url):driver = webdriver.Firefox()driver.get(url)return driver#根據(jù)url獲得文件名def urlToFilename(self, url):m = hashlib.sha256()m.update(url.encode('utf-8'))filename = m.hexdigest()tfile = open(self.mappingFile, 'wb+')tfile.write(filename + ', ' + url + '\n')return filename#保存頁(yè)面內(nèi)容(僅文字)def savePageContent(self, filename, content):tfile= open(self.contentDir + filename,'wb')tfile.write(content)print('writing file-',filename)tfile.close()#處理頁(yè)面中的a標(biāo)簽:#1、將a標(biāo)簽存入相應(yīng)的文件中#2、將其更新如links中 def handleAnchor(self, filename, anchors):hrefs = self.extractHrefFromAnchor(anchors)self.addHrefsToLinks(hrefs)self.saveAnchor(filename, hrefs)#將新提取到的鏈接(未出現(xiàn)過的)加入待處理鏈接中def addHrefsToLinks(self, hrefs):for href in hrefs:if href in self.handledLinks or href in self.unhandledLinks:continueelse:self.unhandledLinks += [href]#保存頁(yè)面鏈接def saveAnchor(self, filename, hrefs):afile= open(self.atagsDir + filename,'wb')afile.write('\n'.join(hrefs))afile.close()#從a標(biāo)簽中提取鏈接def extractHrefFromAnchor(self, anchors):hrefs = []for anchor in anchors:try:href = anchor.get_attribute('href').encode('utf-8')if href in hrefs:continueelse:hrefs += [href]except AttributeError:passexcept selenium.common.exceptions.StaleElementReferenceException:passreturn hrefs#爬取網(wǎng)頁(yè)的入口函數(shù)def scrapy(self, initURL):self.unhandledLinks += [initURL]while len(self.unhandledLinks) != 0:pos = random.randint(0,len(self.unhandledLinks) - 1)print('-pos-',pos)link = self.unhandledLinks[pos]del self.unhandledLinks[pos]driver = self.openPage(link)content = str(driver.find_element_by_xpath(".//html").text.encode('utf-8'))if len(content) > 2*1024: atags = driver.find_elements_by_tag_name("a")filename = self.urlToFilename(link)self.handleAnchor(filename, atags)self.savePageContent(filename,link + '\n' + content)driver.close()pageScrapy = ScrapyPages() pageScrapy.scrapy('http://lvyou.baidu.com/notes/36b629d671563fe1e8927d6a')selenium爬出來的質(zhì)量那是杠杠的。就是每次都要打開火狐代理會(huì)有些慢。沒事,掛機(jī)吧!
除了改用selenium以外,在算法上還有2個(gè)改動(dòng)。
1、以前每次取當(dāng)次要處理的link時(shí),都是從待選link list的第一個(gè)取出。這樣很容易爬到什么登陸界面啊,廣告鏈接啊之類的。后來想,如果從中間取會(huì)不會(huì)好一點(diǎn)?畢竟網(wǎng)頁(yè)的中間一般都是有用的內(nèi)容,可誰知,還有很多引用圖片的網(wǎng)頁(yè),完全陷入圖片的沼澤中了,姐要的是文字文字呀!后來一拍腦袋,哎,用隨機(jī)不就好了
?2、對(duì)爬到的網(wǎng)頁(yè)的文字部分的長(zhǎng)度做判斷,小于2k的就直接舍棄了,畢竟真正有用的文章怎么會(huì)那么小。這樣做有一大損失,就是網(wǎng)頁(yè)直接的若鏈接被打斷了。但也有一大好處,不會(huì)老是爬到廣告頁(yè)上了!不過若鏈接的損失也蠻痛惜的
等等!似乎可以限制路徑的范圍,在幾個(gè)固定的網(wǎng)站里,這樣就可以調(diào)低接受的字符長(zhǎng)度從而獲得站內(nèi)的若鏈接了!!
回宿舍前再記錄一下這靈機(jī)一動(dòng)的改變:
# -*- coding: utf-8 -*- from selenium import webdriver from selenium.webdriver.common.keys import Keys import hashlib import randomclass ScrapyPages:#網(wǎng)頁(yè)內(nèi)容保存目錄contentDir = "G:\\pages\\"#網(wǎng)頁(yè)鏈接保存目錄atagsDir = "G:\\atags\\"#保存網(wǎng)頁(yè)與文件名對(duì)應(yīng)關(guān)系的文件mappingFile = "G:\\mapping"#已處理的鏈接handledLinks = []#待處理的鏈接unhandledLinks = []#打開瀏覽器驅(qū)動(dòng),默認(rèn)為火狐def openPage(self, url):driver = webdriver.Firefox()driver.get(url)return driver#根據(jù)url獲得文件名def urlToFilename(self, url):m = hashlib.sha256()m.update(url.encode('utf-8'))filename = m.hexdigest()tfile = open(self.mappingFile, 'wb+')tfile.write(filename + ', ' + url + '\n')return filename#保存頁(yè)面內(nèi)容(僅文字)def savePageContent(self, filename, content):tfile= open(self.contentDir + filename,'wb')tfile.write(content)print('writing file-',filename)tfile.close()#處理頁(yè)面中的a標(biāo)簽:#1、將a標(biāo)簽存入相應(yīng)的文件中#2、將其更新如links中 def handleAnchor(self, filename, anchors):hrefs = self.extractHrefFromAnchor(anchors)self.addHrefsToLinks(hrefs)self.saveAnchor(filename, hrefs)#將新提取到的鏈接(未出現(xiàn)過的)加入待處理鏈接中def addHrefsToLinks(self, hrefs):for href in hrefs:if href in self.handledLinks or href in self.unhandledLinks:continueelse:if href.find('http://lvyou.baidu.com') != -1:self.unhandledLinks += [href]#保存頁(yè)面鏈接def saveAnchor(self, filename, hrefs):afile= open(self.atagsDir + filename,'wb')afile.write('\n'.join(hrefs))afile.close()#從a標(biāo)簽中提取鏈接def extractHrefFromAnchor(self, anchors):hrefs = []for anchor in anchors:try:href = anchor.get_attribute('href').encode('utf-8')if href in hrefs:continueelse:hrefs += [href]except AttributeError:passexcept selenium.common.exceptions.StaleElementReferenceException:passreturn hrefs#爬取網(wǎng)頁(yè)的入口函數(shù)def scrapy(self, initURL):self.unhandledLinks += [initURL]while len(self.unhandledLinks) != 0:pos = random.randint(0,len(self.unhandledLinks) - 1)print('-pos-',pos)link = self.unhandledLinks[pos]del self.unhandledLinks[pos]driver = self.openPage(link)content = str(driver.find_element_by_xpath(".//html").text.encode('utf-8'))if len(content) > 512: atags = driver.find_elements_by_tag_name("a")filename = self.urlToFilename(link)self.handleAnchor(filename, atags)self.savePageContent(filename,link + '\n' + content)driver.close()pageScrapy = ScrapyPages() pageScrapy.scrapy('http://lvyou.baidu.com/xian')數(shù)據(jù)是從百度旅游爬的,只是做畢設(shè),希望百度不要把我ip加入黑名單…… 23:15
?__________________________
2013.8.4
昨晚雖然沒有設(shè)定最長(zhǎng)等待時(shí)間,導(dǎo)致在掛機(jī)的時(shí)候被一個(gè)圖片頁(yè)面卡住了,不過還是收集到了一些網(wǎng)頁(yè)。今晚改進(jìn)后,再繼續(xù)爬好了。
今天進(jìn)入分詞階段。在網(wǎng)上搜了一下python下面的分詞工具,一個(gè)叫“結(jié)巴”的映入眼簾,一看是掛著github上的就很有好感,嘿嘿。
先隨便拿一個(gè)昨天爬下來的網(wǎng)頁(yè)試試。
?文件1.txt
http://lvyou.baidu.com/notes/2b55cfda9f42fb3bf11afb27 登錄 | 注冊(cè) 目的地|游記 百度一下 首頁(yè) 目的地指南 攻略下載 游記 畫冊(cè) 首頁(yè) >游記攻略 >長(zhǎng)沙鳳凰張家界9日之旅 長(zhǎng)沙鳳凰張家界9日之旅 滿園含香 2013年07月出發(fā) 從上海到 張家界 9天 人均:1000-3000(元) 分享到: 回 復(fù) 3 | 瀏 覽 47 0 0 發(fā)表游記攻略 互動(dòng)交流 只看游記 游記大圖 選中文字,就可以引用到回復(fù)中,試試吧:) 滿園含香 前言 長(zhǎng)沙 - 鳳凰 - 張家界 - 天門山 - 猛洞河漂流 - 芙蓉鎮(zhèn)之旅 第一天:張家界游記之第一站--長(zhǎng)沙完美終結(jié)篇 長(zhǎng)沙 - 岳麓書院 - 橘子洲 第二天:張家界游記第二站---鳳凰古城之浪漫魅惑篇 鳳凰 - 虹橋 - 楊家宅 - 陳斗南故居 - 沱江 第三天:張家界游記之第三站--作別鳳凰挺進(jìn)張家界篇 鳳凰沱江 - 張家界大成山水 第四天:張家界游記之第四天--金鞭溪邊畫中游篇 張家界國(guó)家森林公園 - 金鞭溪 第五天: 張家界游記之第五天--天子山景區(qū)唯美篇 老屋場(chǎng) - 神兵聚會(huì) - 天子山景區(qū)'賀龍公園` - 十里畫廊 - 黃龍洞 - 寶峰湖 選中文字加入計(jì)劃 隨時(shí)收集有效信息 只看樓主 | 回復(fù) 關(guān)注 滿園含香 發(fā)表于2013-08-04 02:37 前言 長(zhǎng)沙- 鳳凰- 張家界- 天門山- 猛洞河漂流- 芙蓉鎮(zhèn)之旅 1樓7/13.1)上航FM9395 上海虹橋9:05起飛,10:45到達(dá)長(zhǎng)沙到達(dá)長(zhǎng)沙后在大廳集合,一共8人,先到酒店登記入住,放行李。入住錦江之星(長(zhǎng)沙火車站店)地址:長(zhǎng)沙市芙蓉區(qū)車站北路46號(hào)(近長(zhǎng)沙火車站) 酒店電話:0731-88316888.阿波羅廣場(chǎng)是大巴去鳳凰的集合點(diǎn),我們住的酒店離阿波羅廣場(chǎng)非常近,步行100米左右。2) 坡子街----火宮殿,品味長(zhǎng)沙小吃1-2.長(zhǎng)沙火車站到坡子街:可以坐旅3路(至坡子街站下),368路(至解放西路口站下步行300M左右到坡子街),112路(至解放西路口站下步行260M左右到坡子街)。約30-40分鐘。 長(zhǎng)沙火車站到南門口:可以乘坐202路、108路在南門口下。約30分鐘。 3.這兩個(gè)地方距離不遠(yuǎn),都離黃興步行街很近。123路就3站,10分鐘左右。建議天氣不曬可以選擇步行。實(shí)際上我們后來沒有去坡子街,看完岳麓書院,橘子洲頭,就順路找了一家在湘江邊的飯店,一邊欣賞煙花一邊吃晚飯,倒也不錯(cuò)。3) 中國(guó)四大名亭之一—愛晚亭,遠(yuǎn)眺指點(diǎn)江山的橘子洲頭,岳麓書院4) 游輪暢游湘江。(周六晚湘江有煙火)PS: 提前定第二天到鳳凰的車票 ,我們?nèi)P凰的票是在網(wǎng)上訂的,只是定個(gè)位子,上車再付錢,感覺比較放心。導(dǎo)游提前一天電話通知我集合時(shí)間及地點(diǎn)。7/14 1)一早乘旅游大巴到鳳凰,估計(jì)5.5小時(shí)。我們是早上7點(diǎn)半發(fā)車,下午2點(diǎn)才到鳳凰。晚上入住鳳凰江天旅游度假村,酒店地址:沱江鎮(zhèn)虹橋路2號(hào)(古城內(nèi),近虹橋)也是在藝龍上定的。我們?nèi)胱『蟀l(fā)現(xiàn)這家酒店位置非常好,就在虹橋頭,屬于鬧中取靜的位置,第二天導(dǎo)游集合的地點(diǎn)就在我們這家酒店,說明咱選的位置好呀。2)晚飯后,欣賞鳳凰古城的夜景 7/15 1) 清晨的鳳凰一定不能錯(cuò)過,在鳳凰吃過中飯后,采購(gòu)食物,出發(fā)到張家界。2)在鳳凰縣城北汽車站乘車,大約4小時(shí),到張家界。實(shí)際上我們是早8點(diǎn)半發(fā)車,下午2點(diǎn)半才到張家界。一路上顛簸不停,沒有走高速,我還暈車,非常的難受。這里說明一下,酒店可以預(yù)定鳳凰到張家界的長(zhǎng)途車票,這樣可以保證第二天到了汽車站就走,不會(huì)落空。票價(jià)70元。3)晚上入住張家界大成山水國(guó)際大酒店,酒店地址:張家界市大庸西路,酒店電話:0744-8889999。大成山水是5星級(jí)酒店,可以在藝龍,攜程上預(yù)定酒店的限時(shí)限購(gòu)優(yōu)惠,我們酒店在7月的旺季,才419元一間,可謂超值。當(dāng)然要早下手。 7/16 1)在酒店享用一頓豐盛的早餐,和張家界客棧老板碰頭,開始4天的張家界之旅,2)具體行程安排有張老板制定,張老板的電話是150-744-23210挺實(shí)誠(chéng)的土家漢子一早帶我們?nèi)埣医缟止珗@,沿著金鞭溪一直走,走到白龍?zhí)焯?#xff0c;上袁家界,看哈利路亞山,之后乘環(huán)保車到天子山丁香榕,他的客棧就在那里,晚上我們?nèi)胱∷目蜅!C窬?#xff0c;挺有家的感覺,坐在院落里吃西瓜,吃晚飯,用WIFI看快本,還是很不錯(cuò)的。山上的居住條件一般,大家不要想象的有多好,只是住一晚而已。 7/17 早上5點(diǎn)我們到老屋場(chǎng)看日出,神兵點(diǎn)將,空中田園,我們給了他包車費(fèi)200元,貌似他也沒賺,直接給了包車的司機(jī)。一大早陪我們看日出,辛苦了。 在他家吃過早飯后,我們乘環(huán)保車到賀龍公園。游覽天子山的十里畫廊,下午去了黃龍洞,寶峰湖,這一天的行程可謂安排的緊湊呀。晚上回到張家界市區(qū),住在天門山索道對(duì)面的緯地酒店,掛4星,是張老板定的房間。7/18 因?yàn)榫频昃驮谔扉T山景區(qū)的對(duì)面,所以不用趕早,吃過酒店的自助早餐之后再上山。,天門山門票包含大索道的費(fèi)用,它這個(gè)索道有上站,中站,下站。張導(dǎo)建議我們先乘索道到上站,看玻璃棧道,之后乘上站索道下行至中站,乘景區(qū)環(huán)保車去天門洞,爬999級(jí)臺(tái)階上到天門洞,之后乘環(huán)保車到中站,乘索道到下站。我們因?yàn)橛兴I(lǐng)路沒走冤枉路。在景區(qū)碰到一對(duì)自助游的夫妻倆,多買了小索道的往返票,還走了好多路。晚上接著住在緯地酒店。 7/19 一早張導(dǎo)包車帶我們?nèi)ッ投春悠?#xff0c;中午在芙蓉鎮(zhèn)吃飯,順便到芙蓉鎮(zhèn)看看。本來不報(bào)太大希望,去了以后才發(fā)現(xiàn)這個(gè)景點(diǎn)還是很不錯(cuò)的。大人80元一張,小孩不要錢。到這里張導(dǎo)就完成了歷史使命了,他本來送我們到火車站,一來我們的火車是第二天下午13點(diǎn)鐘的,再一個(gè)張家界的出租車很便宜也好叫,所以我們就不麻煩他了,讓他早點(diǎn)回家見他的小女兒吧。說明一下,我們和他談的價(jià)錢是1人1600元,4天3晚的行程,包吃包住包車包門票,小孩的門票也是退還我們的。所以我們8個(gè)人實(shí)際支出11472元。之前看網(wǎng)上都說導(dǎo)游會(huì)把我們散團(tuán)轉(zhuǎn)賣給其他的團(tuán),還好,我們張導(dǎo)一直陪著我們,晚上入住張家界逸塵國(guó)際大酒店。酒店地址:永定區(qū)濱河路188-186號(hào)。酒店電話:0744-8222222. 這家酒店是來之前我在藝龍上定的,4星,319元一間。7/20 睡到自然醒,享受酒店的豐盛早餐,外出采購(gòu)火車上的食物,下午13點(diǎn)乘火車到上海。我們住的酒店附近有一家賣進(jìn)口食品的超市,東西都比上海便宜,品質(zhì)也是一樣一樣的。 7/21 中午時(shí)分抵達(dá)上海南站,回到溫馨的家,結(jié)束張家界和鳳凰之旅。以上就是我們長(zhǎng)沙鳳凰張家界一行的住宿旅游行程單,我負(fù)責(zé)訂酒店訂機(jī)票訂車票訂導(dǎo)游,總之一切和錢打交道的事;含煙負(fù)責(zé)花枝招展,一切小資的事情,我們行程游記也是她一路記載一路上傳,她寫得那么好,我就不用班門弄斧了。看下段游記 | 只看樓主 | 回復(fù) 關(guān)注 0 0 共10篇帖子 | 回復(fù)(3) | 瀏覽(47) 分享到: 回復(fù) 您尚未登錄哦,請(qǐng)登錄后回復(fù)。 登錄 | 注冊(cè) 發(fā)布 評(píng)論 0 0 分享到 快速導(dǎo)航 相關(guān)目的地 張家界 相關(guān)游記 煙雨鳳凰——遇見,就是一生的眷戀(&張家界,黃龍洞,長(zhǎng)沙) 78113 pichai_305 2012至2013兩個(gè)2B青年的鳳凰、張家界時(shí)光記憶 31123 愛旅行的y小姐 【湖了個(gè)南】張家界-鳳凰-長(zhǎng)沙漫畫游記~重磅回歸,勿容錯(cuò)過··· 40832 貓火火 如何寫出精華游記 關(guān)注微博 下載APP ?2013 Baidu 使用百度前必讀 百度旅游用戶協(xié)議 聯(lián)系我們 【免費(fèi)】臺(tái)灣9日自由行,美景美食美人,應(yīng)有盡有借助“結(jié)巴”寫的分詞測(cè)試代碼
# -*- coding: utf-8 -*- import jieba import jieba.analyse from collections import Counterjieba.load_userdict('dict.txt') handler = open('1','r') content = handler.read() handler.close() seg_list = jieba.cut(content) after = '\n'.join(seg_list).encode('utf-8') wfile = open('2','wb') wfile.write(after) wfile.close()tags = jieba.analyse.extract_tags(content,100) counts = [] countTags = '' splitAfter = after.split('\n') tfile = open('count','wb+') for tag in tags:words = tag.encode('utf-8')count = splitAfter.count(words)tfile.write('{},{}\n'.format(words,count)) tfile.close()使用的自定義詞典 dict.txt
阿波羅廣場(chǎng) 5 坡子街 5 黃興步行街 3 橘子洲頭 3 愛晚亭 1 城北汽車站 2 大成山水國(guó)際大酒店 2 大庸西路 2 哈利路亞山 3 寶峰湖 2 緯地酒店 2 天門山景區(qū) 2 逸塵國(guó)際大酒店 1分詞并排序后的結(jié)果 count.txt
張家界,30 鳳凰,21 酒店,21 游記,16 我們,30 長(zhǎng)沙,12 坡子街,6 索道,7 入住,7 天子山,4 環(huán)保車,4 長(zhǎng)沙火車站,4 張導(dǎo),4 2013,4 天門山,4 回復(fù),6 行程,5 導(dǎo)游,4 虹橋,4 黃龍洞,3 藝龍,3 含香,3 10,3 芙蓉鎮(zhèn),4 晚上,6 之旅,4 金鞭,3 猛洞河,3 岳麓書院,3 登錄,4 步行,4 第二天,5 滿園,3 景區(qū),4 攻略,3 包車,3 地址,4 下午,5 電話,5 漂流,3 老板,4 客棧,3 湘江,3 車票,3 百度,3 門票,3 早餐,3 旅游,4 目的地,3 可以,7 阿波羅廣場(chǎng),2 緯地酒店,2 點(diǎn)半,2 橘子洲頭,2 日之旅,2 寶峰湖,2 口站,2 鳳凰古城,2 上定,2 47,2 30,2 13,2 0744,2 一早,3 上海,5 分享,3 老屋,2 這家,3 樓主,2 發(fā)車,2 第五天,2 大巴,2 分鐘,3 神兵,2 沱江,2 首頁(yè),2 第四天,2 賀龍,2 畫廊,2 不錯(cuò),3 門洞,2 選中,2 前言,2 吃晚飯,2 豐盛,2 之后,4 飯后,2 日出,2 西路,2 位置,3 十里,2 說明,3 預(yù)定,2 山水,2 大成,2 一路上,2 火車,2 小孩,2 欣賞,2 集合,2在自己的問題域內(nèi)定義個(gè)詞典還是挺有用的,不然很多詞會(huì)被拆掉。python的list.count()還是相當(dāng)給力的。本來有個(gè)Counter函數(shù)應(yīng)該更厲害的,不過試了一下,似乎是只能統(tǒng)計(jì)字母的個(gè)數(shù),憂傷……
總結(jié)
以上是生活随笔為你收集整理的网络爬虫Python试验的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Excel表格防止重复录入数据
- 下一篇: 深度学习Dya1-初识Python(Py