requests爬取去哪兒網站
阿新 • • 發佈:2019-02-04
閒來無事,所以爬下去哪兒網站的旅遊景點資訊,爬取網頁之前,最重要的是分析網頁的架構。
1. 選擇要爬取的網頁及定位自己要爬取的資訊
url=http://piao.qunar.com/ 爬取全國熱門城市的境內門票
首先要得到全國熱門城市的城市名及它們背後的連結
2. 根據獲得的連結進入對應的頁面
進一步分析頁面,將我們要的資料一個個找出來
3. 得到頁面的下一頁
這裡我為什麼要把後面這張圖片拿出來是因為我要根據最大頁數來遍歷每一頁,倒數第二個a標籤中的資料是頁數資訊
到這裡我們就將我們的思路屢清楚了:
1.首先根據初始給的url,解析該url得到城市的城市名及背後的連結
2.再根據得到的連結解析出其中包含很多頁的每一頁連結
3.根據得到的每一個的連結,再來對每一頁的資訊解析
4.將解析後的資料存入到MySQL資料庫中
4. 設計資料庫
5. 直接上程式碼
import requests from bs4 import BeautifulSoup import re import pymysql # 解析出每個城市及其該城市對應的url def parse_city(url): html = requests.get(url,headers=headers) html = html.text soup = BeautifulSoup(html,'lxml') city = soup.find_all('ul',{'class':'mp-sidebar-list','mp-role':'hotCityList'})[0].find_all('li') for i in city: # 得到每個城市的名字和對應的url city_name = i.a.text city_url = i.a['href'] city_url='http://piao.qunar.com'+city_url city_page(city_name,city_url) # 解析出每個城市的url的下一頁 def city_page(city_name,city_url): html = requests.get(city_url,headers=headers) html = html.text soup = BeautifulSoup(html,'lxml') page = soup.find_all('div',{'class':'pager'})[0].find_all('a') # 得到a標籤中的href page_url = page[0]['href'] # 得到下一頁的url,這個url由我們來指定,只需把頁數前面的字串匹配出來即可 page_select_url = re.findall('(.*page=)',page_url)[0] # 將完整的頁數的url拼接起來 page_select_url = 'http://piao.qunar.com'+page_select_url # 這裡選-2是有深意的,因為在選擇每一頁的地方倒一是下一頁,而倒二則是尾頁數 page_num = int(page[-2].text) print('有%s頁的資料'%page_num) for i in range(1,page_num+1): # 遍歷得到某個城市中所有頁數 print('第%d頁資訊'%i) parse_page_url = page_select_url+str(i) print('網頁地址:',parse_page_url) # 將每一頁的url都傳遞到parse_page中進行解析 parse_page(city_name,parse_page_url) # 解析每個城市每一頁的資訊 def parse_page(city_name,parse_page_url): html = requests.get(parse_page_url,headers=headers) html = html.text soup = BeautifulSoup(html,'lxml') jingdian = soup.find_all('div',{'class':'result_list','id':'search-list'})[0].find_all('div',{'class':'sight_item'}) for c in jingdian: # 景點名 jd_name = c.find_all('a',{'data-click-type':'l_title','class':'name'})[0].text # 景點級別,有的景區無級別,所以要設定一個異常 try: jd_jb = c.find_all('span',{'class':'level'})[0].text except: jd_jb='普通景區' # text得到的是 地址:北京市東城區景山前街4號 這種格式,所以以空格拆分,取後面那個 jd_address = c.find_all('p',{'class':{'address','color999'}})[0].text.split()[-1] # 景點介紹 jd_jieshao = c.find_all('div',{'class':{'intro','color999'}})[0].text # 景點價格,有的是免費,並無價格這一引數,所以設定一個異常 try: jd_price = c.find_all('span',{'class':'sight_item_price'})[0].find_all('em')[0].text except: jd_price=0 # 有的是免費,並銷量這一引數,所以設定一個異常 try: jd_xiaoliang = c.find_all('span',{'class':'hot_num'})[0].text # 景點銷量 jd_xiaoliang=int(jd_xiaoliang) except: jd_xiaoliang=0 print('{0} {1} {2} {3} {4}'.format(jd_name,jd_jb,jd_jieshao,jd_price,jd_xiaoliang)) mysql(city_name,jd_name,jd_jb,jd_jieshao,jd_price,jd_xiaoliang) # 定義一個類,將連線MySQL的操作寫入其中 class down_mysql: def __init__(self,city_name,jd_name,jd_jb,jd_jieshao,jd_price,jd_xiaoliang): self.city_name = city_name self.jd_name = jd_name self.jd_jb = jd_jb self.jd_jieshao = jd_jieshao self.jd_price = jd_price self.jd_xiaoliang = jd_xiaoliang self.connect = pymysql.connect( host = 'localhost', db = 'test', port = 3306, user = 'root', passwd = '123456', charset = 'utf8', use_unicode = False ) self.cursor = self.connect.cursor() # 儲存資料到MySQL中 def save_mysql(self): sql = "insert into qu_na(city_name,jd_name,jd_jb,jd_jieshao,jd_price,jd_xiaoliang) VALUES (%s,%s,%s,%s,%s,%s)" try: self.cursor.execute(sql,(self.city_name,self.jd_name,self.jd_jb,self.jd_jieshao,self.jd_price,self.jd_xiaoliang)) self.connect.commit() print('資料插入成功') except: print('資料插入錯誤') def mysql(city_name,jd_name,jd_jb,jd_jieshao,jd_price,jd_xiaoliang): # 新建類,將資料儲存在MySQL中 down = down_mysql(city_name,jd_name,jd_jb,jd_jieshao,jd_price,jd_xiaoliang) down.save_mysql() if __name__=='__main__': headers = { 'User-Agent': 'Mozilla/4.0(compatible;MSIE 5.5;Windows NT)', } start_url='http://piao.qunar.com/' parse_city(start_url)
執行程式
然後再來看我們的MySQL資料庫
看到景點名這個欄位空了這麼多我就知道我表設計錯了,這個欄位給大了,總而言之還算是爬下來了