用Requests + BeautifulSoup 爬取Tripadvistor
爬取一個(gè)網(wǎng)頁需要兩步:
1.服務(wù)器與本地的接交換機(jī)制
2.解析真實(shí)網(wǎng)頁的方法
1.服務(wù)器與本地的交換機(jī)制
瀏覽網(wǎng)頁的過程是通過瀏覽器向網(wǎng)站所在的服務(wù)器發(fā)送一個(gè)Request
萎坷,同時(shí)服務(wù)器回應(yīng)一個(gè)Response
叉信,這就是一個(gè)簡單的HTTP協(xié)議
吐辙。
每一個(gè)Request
請求包括很多種方法帜平,目前(HTTP2.0
)的方法有:get
嗅钻、post
、head
恶耽、put
衅鹿、options
、connect
塞颁、trace
浦箱、delete
,這八種方法吸耿。 GET和POST是最常用的兩種方法。
爬蟲抓取一個(gè)網(wǎng)頁酷窥,實(shí)質(zhì)上就是模擬這兩種方法咽安。
GET/page_one.html HTTP/1.1 Host:www.sample.com
以上是一個(gè)簡單的get
方法發(fā)送的請求方式,可以看出請求得到的信息包括頁面的內(nèi)容蓬推,協(xié)議的版本信息妆棒,以及網(wǎng)頁的主域名。
一個(gè)正常打開的頁面沸伏,返回的狀態(tài)碼應(yīng)該是200
糕珊,無法打開的頁面一般返回403
或者404
。
2.爬取Tripadvisor頁面信息
爬取頁面信息的步驟:
1.導(dǎo)入所需要的庫
2.使用requests
請求要爬取的網(wǎng)頁
3.解析網(wǎng)頁
4.描述要爬取的元素位置
#_*_ coding:utf-8 _*_
from bs4 import BeautifulSoup
import requests
import time
# part1
'''
url = 'http://www.tripadvisor.cn/Attractions-g60763-Activities-New_York_City_New_York.html'
wb_data = requests.get(url)
soup = BeautifulSoup(wb_data.text, 'lxml')
# 1.描述要爬取元素的位置
# Copy一下title的selector毅糟,測試一下結(jié)果
# titles = soup.select('#ATTR_ENTRY_105127 > div.property_title > a')
# print titles
# 打開原網(wǎng)頁红选,查找title的父標(biāo)簽樣式,發(fā)現(xiàn)在每一個(gè)<div class="property_title">下面的<a>標(biāo)簽中的內(nèi)容就是title
# 那么更新一下titte的解析語句
titles = soup.select('div.property_title > a[target="_blank"]')
# 2.篩選所需要的元素
# 頁面中存在的圖片不一定全是所需要的姆另,可以根據(jù)圖片的屬性(大欣摺)對圖片進(jìn)行篩選
imgs = soup.select('img[width="160"]')
# 對其他的元素進(jìn)行篩選
# tags一般是多對一的關(guān)系,所以在tags的父類標(biāo)簽進(jìn)行篩選
cates = soup.select('div.p13n_reasoning_v2')
# 3.整理并篩選所需信息
for title, img, cate in zip(titles, imgs, cates):
data = {
'title': title.get_text(),
'img': img.get('src'),
'cate':list(cate.stripped_strings)
}
print data,'\n*************************************\n'
# 運(yùn)行上述代碼后發(fā)現(xiàn)迹辐,爬取的圖片鏈接是一樣的蝶防,也就意味著圖片信息沒有爬取下來
# 這是由于站點(diǎn)的反爬蟲機(jī)制造成的,站點(diǎn)的圖片加載是通過JavaScript控制的明吩,暫時(shí)先不用管這些
# 4.使爬蟲為登錄站點(diǎn)的狀態(tài)间学,構(gòu)造向服務(wù)器提交的參數(shù):headers
# 重新完成一個(gè)爬蟲代碼
'''
# part2
'''
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36',
'Cookie':'__utma=55896302.1244431692.1455603774.1455603774.1455603774.1; __utmc=55896302; =',
}
url_saves = 'http://www.tripadvisor.cn/Saves#207971'
wb_data = requests.get(url_saves, headers=headers)
soup = BeautifulSoup(wb_data.text, 'lxml')
titles = soup.select('a.location-name')
imgs = soup.select('img.photo_image')
metas = soup.select('span.format_address')
for title, img, meta in zip(titles, imgs, metas):
data = {
'title':title.get_text(),
'img':img.get('src'),
'meta':list(meta.stripped_strings),
}
print data
'''
# 構(gòu)造函數(shù)
url_saves = 'http://www.tripadvisor.cn/Saves#207971'
url = 'http://www.tripadvisor.cn/Attractions-g60763-Activities-New_York_City_New_York.html'
# 連續(xù)爬取30頁的網(wǎng)頁信息,發(fā)現(xiàn)每一頁的區(qū)別在于 oa30 這個(gè)參數(shù)上印荔,每一頁的站點(diǎn)在這個(gè)數(shù)值的基礎(chǔ)上增加30
# 所以可以用以下的格式進(jìn)行爬取
urls = ['http://www.tripadvisor.cn/Attractions-g60763-Activities-oa{}-New_York_City_New_York.html#ATTRACTION_LIST'.format(str(i)) for i in range(30,930,30)]
headers = {
'User-Agent':'Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.109 Safari/537.36',
'Cookie':'__utma=55896302.1244431692.1455603774.1455603774.1455603774.1; __utmc=55896302; =',
}
def get_attractions(url, data=None):
wb_data = requests.get(url)
time.sleep(4)
soup = BeautifulSoup(wb_data.text, 'lxml')
titles = soup.select('div.property_title > a[target="_blank"]')
imgs = soup.select('img[width="160"]')
cates = soup.select('div.p13n_reasoning_v2')
for title, img, cate in zip(titles, imgs, cates):
data = {
'title':title.get_text(),
'img': img.get('src'),
'cate':list(cate.stripped_strings),
}
print data,'\n','*'*50,'\n'
def get_favs(url, data=None):
wb_data = requests.get(url, headers=headers)
soup = BeautifulSoup(wb_data.text, 'lxml')
titles = soup.select('a.location-name')
imgs = soup.select('img.photo_image')
metas = soup.select('span.format_address')
if data == None:
for title, img, meta in zip(titles, imgs, metas):
data = {
'title':title.get_text(),
'img':img.get('src'),
'meta':list(meta.stripped_strings),
}
print data,'\n','*'*50,'\n'
for single_url in urls:
get_attractions(single_url)
# 6.爬取多連續(xù)頁的資料
代碼演示了簡單的爬蟲菱鸥,帶Cookie
的爬蟲,以及連續(xù)爬取多個(gè)頁面的爬蟲躏鱼。
為了應(yīng)對站點(diǎn)的反爬蟲機(jī)制同窘,也可以利用模擬手機(jī)端登錄的方式進(jìn)行站點(diǎn)的爬扰璩唷:
# 手機(jī)端抓取網(wǎng)頁信息
from bs4 import BeautifulSoup
import requests
headers = {
'User-Agent':'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1',
}
url = 'http://www.tripadvisor.cn/Attractions-g60763-Activities-oa30-New_York_City_New_York.html'
mb_data = requests.get(url, headers=headers)
soup = BeautifulSoup(mb_data.text, 'lxml')
imgs = soup.select('div.thumb.thumbLLR.soThumb > img')
for i in imgs:
print i.get('src')
從代碼中可以看出麻掸,模擬手機(jī)端的爬蟲與一般的爬蟲非常的相似熟吏,區(qū)別在于headers
中的User-Agent
是不一樣的廊散,這個(gè)也是非常簡單的慰技,Chrome
瀏覽器可以通過很簡單的方式進(jìn)行手機(jī)端登錄站點(diǎn)的模擬沃呢。具體實(shí)現(xiàn)可以在網(wǎng)上查找一下气堕。