當前位置:菜譜大全網 - 美食做法 - python 可以在螞蜂窩上爬數據嗎

python 可以在螞蜂窩上爬數據嗎

當然可以。

爬蟲代碼分析

我們首先需要爬取得頁面為?

我們可以看到url為www.mafengwo.cn/group/s.php?q=曼谷&p=1&t=cate&kt=1。主要參數有q?,p?,t,其中q為城市名,p為頁碼,t為分類,cate為美食,kt為不影響參數。

需要獲取該頁面,detail為域名以後的參數,這個函數可以用於獲得域名主頁下的網頁

#獲取下級頁面

def getDetailPage(detailURL):

try:

url = ""+detailURL"

request = urllib2.Request(url)

response = urllib2.urlopen(request)

#利用urllib2的Request方法返回壹個request對象並用urlopen打開

page = response.read()

#用read()方法讀取頁面內容,Input: print page Output: 頁面html

pageCode = re.sub(r'<br[ ]?/?>', '\n', page)

#去掉html裏的回車空行

return pageCode

except urllib2.URLError, e:

if hasattr(e, "reason"):

print e.reason

return None12345678910111213141516

獲得每家美食店鋪的鏈接,首先進行元素檢查查看鏈接位於的位置

#獲得美食單頁店鋪鏈接

def getFoodHref(self,pageid):

url = "/group/s.php?q="+self.city+"&p=" +str(pageid)+ "&t=cate&kt=1"

page = getDetailPage(url) #調用getDetailPage獲得頁面

soup = BeautifulSoup(page,'html.parser') #用BeautifulSoup進行頁面解析

FoodHref = []

FoodLists = ?soup.find(name="div",attrs={'data-category':'poi'}).ul

FoodHrefList = FoodLists.find_all("h3") #找出<div class="_j_search_section" data-category="poi">標簽下所有的<h3>標簽的內容,結果為店鋪列表的html

for FoodHrefs in FoodHrefList:

FoodWebsite = FoodHrefs.a['href'] #對列表循環找出a標簽href屬性的值,即為店鋪的url

FoodHrefShort = str(FoodWebsite).replace('','') #去掉url前的域名,以便等會調用getDetaiL函數,傳入它獲得店鋪頁面

FoodHref.append(FoodHrefShort) return FoodHref123456789101112131415161718

接下來再次調用getDetailPage(),傳入FoodHref,即可可以獲得店鋪的頁面,通過BeautifulSoup進行信息獲取了。但我在抓取的時候遇到壹個問題。?

這是壹個信息齊全的店鋪,但有的店鋪沒有網址,沒有交通信息該怎麽辦。比如這個?

經過元素檢查發現標簽也是壹樣的,無法通過標簽特有的屬性或者class的值進行定向抓取。用<div class="bd">的子節點兄弟節點查也不行。後來想出壹個方法。

先寫壹個匹配函數hasAttr,list參數為壹個中文的完整信息名列表,在getShopInfo方法裏通過循環列表內容與抓取的<div class="bd">標簽內容匹配,如果返回True則表示存在該信息項,否則繼續匹配下壹項。比如上面的圖,先匹配簡介,匹配失敗,繼續匹配英文名字,也失敗,知道匹配到地址,成功,保存地址下壹個標簽的內容。直到獲得所有信息。

#判斷是否存在信息列表

def hasAttr(self,list):

soup = BeautifulSoup(page, 'html.parser')

col = soup.find("div", class_="col-main").find("div", class_="bd")

str_col = str(col) if list in str_col: return True

else: return False

#抓取店鋪信息

def getShopInfo(self,page):

shopInfoList = ['brief','localName','location', 'telephone', 'website', 'ticket', 'openTime','shopName','shopScore']

infoItem = ['簡介', '英文名稱', '地址', '電話', '網址', '門票', '開放時間','名字','星評']

soup = BeautifulSoup(page, 'html.parser')

shopName = soup.find("div", class_="wrapper").h1.string

shopScore = soup.find("div", class_="col-main").span.em.string for i in range(0,6): #信息項循環查找

if self.hasAttr(page, infoItem[i]):

pattern_shopinfo = re.compile( '<div class="col-main.*?<div class="bd">.*?'+ infoItem[i] +'</h3>.*?>(.*?)</p>', re.S)

shopInfos = re.findall(pattern_shopinfo, page) #存在該項則用正則取出其標簽內容

for shopInfo in shopInfos:

shopInfoList[i] = shopInfo else: #繼續查找下壹項

continue

shopInfoList[7] = shopName

shopInfoList[8] = shopScore return shopInfoList1234567891011121314151617181920212223242526272829303132333435

最後將數據加入字典,如果壹鍵對多值,比如dict = {a:[]},調用set default(鍵名,[]).append(列表值)?

dict.setdefault('comment',[]).appnd(comment)

然後json.dumps(dict,indent=1).decode("unicode_escape")。indent參數是為了以json樹形式表現出數據,如果內容中有中文要用decode("unicode_escape"),否則結果為”\u”的unicode編碼