用Requests + BeautifulSoup 爬取Tripadvistor
爬取一个网页需要两步:
1.服务器与本地的接交换机制
2.解析真实网页的方法
1.服务器与本地的交换机制
浏览网页的过程是通过浏览器向网站所在的服务器发送一个Request
,同时服务器回应一个Response
,这就是一个简单的HTTP协议
。
每一个Request
请求包括很多种方法,目前(HTTP2.0
)的方法有:get
、post
、head
、put
、options
、connect
、trace
、delete
,这八种方法。 GET和POST是最常用的两种方法。
爬虫抓取一个网页,实质上就是模拟这两种方法。
GET/page_one.html HTTP/1.1 Host:www.sample.com
以上是一个简单的get
方法发送的请求方式,可以看出请求得到的信息包括页面的内容,协议的版本信息,以及网页的主域名。
一个正常打开的页面,返回的状态码应该是200
,无法打开的页面一般返回403
或者404
。
2.爬取Tripadvisor页面信息
爬取页面信息的步骤:
1.导入所需要的库
2.使用requests
请求要爬取的网页
3.解析网页
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,测试一下结果
# titles = soup.select('#ATTR_ENTRY_105127 > div.property_title > a')
# print titles
# 打开原网页,查找title的父标签样式,发现在每一个<div class="property_title">下面的<a>标签中的内容就是title
# 那么更新一下titte的解析语句
titles = soup.select('div.property_title > a[target="_blank"]')
# 2.筛选所需要的元素
# 页面中存在的图片不一定全是所需要的,可以根据图片的属性(大小)对图片进行筛选
imgs = soup.select('img[width="160"]')
# 对其他的元素进行筛选
# tags一般是多对一的关系,所以在tags的父类标签进行筛选
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'
# 运行上述代码后发现,爬取的图片链接是一样的,也就意味着图片信息没有爬取下来
# 这是由于站点的反爬虫机制造成的,站点的图片加载是通过JavaScript控制的,暂时先不用管这些
# 4.使爬虫为登录站点的状态,构造向服务器提交的参数:headers
# 重新完成一个爬虫代码
'''
# 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
'''
# 构造函数
url_saves = 'http://www.tripadvisor.cn/Saves#207971'
url = 'http://www.tripadvisor.cn/Attractions-g60763-Activities-New_York_City_New_York.html'
# 连续爬取30页的网页信息,发现每一页的区别在于 oa30 这个参数上,每一页的站点在这个数值的基础上增加30
# 所以可以用以下的格式进行爬取
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.爬取多连续页的资料
代码演示了简单的爬虫,带Cookie
的爬虫,以及连续爬取多个页面的爬虫。
为了应对站点的反爬虫机制,也可以利用模拟手机端登录的方式进行站点的爬取:
# 手机端抓取网页信息
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')
从代码中可以看出,模拟手机端的爬虫与一般的爬虫非常的相似,区别在于headers
中的User-Agent
是不一样的,这个也是非常简单的,Chrome
浏览器可以通过很简单的方式进行手机端登录站点的模拟。具体实现可以在网上查找一下。
网友评论