使用requests爬取马蜂窝中国旅游热门城市

  本次爬取的是马蜂窝网的中国旅游热门城市板块,爬取字段有城市名称(中英名)、城市主页url、图片url、去过人数、旅游城市描述,最后保存到本地mysql数据库。




——————— 直接上代码,不多说 ————————
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# -*- coding: utf-8 -*-
"""
Created on Sat Oct 22 18:28:26 2016

@author: bgods
"""

import MySQLdb
import requests
import json
from lxml import etree



class MafengwoSpider:
def __init__(self,con):
self.con = con
# 初始化页面,从第一页开始爬取
self.page = 1
self.url = 'http://www.mafengwo.cn/mdd/base/list/pagedata_citylist'
# 定义表头
self.headers = {
'Host': 'www.mafengwo.cn',
'User-Agent': 'Mozilla/5.0 (Windows NT 6.3; WOW64; rv:47.0) Gecko/20100101 Firefox/47.0',
'Accept': 'application/json, text/javascript, */*; q=0.01',
'Accept-Language': 'zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3',
'Accept-Encoding': 'gzip, deflate',
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
'X-Requested-With': 'XMLHttpRequest',
'Referer': 'http://www.mafengwo.cn/mdd/citylist/21536.html',
'Content-Length': '20',
'Connection': 'keep-alive'
}

def GetPage(self):
# 分析发现数据是通过post请求方式获取的,
# 提交参数包含mddid(目测是该板块的id,该参数不变)、page(页码,改变值可以请求到不同页面);
# 响应的数据json格式,使用json包来解析
data = {"mddid" : "21536", "page" : self.page}
html = requests.post(url=self.url, data=data, headers=self.headers)
html = json.loads(html.text)

lists = etree.HTML(html['list'])
L = lists.xpath('//li')

# 定义data列表,用于保存该页面提取的数据
data = []
for l in L:
l = etree.HTML(etree.tostring(l))
home_url = l.xpath('//div[@class="img"]/a/@href')
home_img = l.xpath('//li/div/a/img/@data-original')
cnname = l.xpath('//div[@class="title"]/text()[1]')
enname = l.xpath('//p[@class="enname"]/text()')
visit_nums = l.xpath('//div[@class="nums"]/b/text()')
detail = l.xpath('//div[@class="detail"]/text()')

d = {}
d["home_url"] = self.d(home_url).strip()
d["home_img"] = self.d(home_img).strip()
d["cnname"] = self.d(cnname).strip()
d["enname"] = self.d(enname).strip()
d["visit_nums"] = self.d(visit_nums).strip()
d["detail"] = self.d(detail).strip()
data.append(d)

# 遍历列表data,把数据写入到mysql数据库
for d in data:
self.write_sql(d)
#print d

# 判断当前所在页码,并判断是否还有下一页,如果有则继续爬取,否则停止爬取
pages = etree.HTML(html['page'])
print "Start crawling the page:",pages.xpath('//span[@class="pg-current"]//text()')[0]

if len(pages.xpath('//a[@class="pg-next _j_pageitem"]//text()'))==0:
# 所有页面爬取完
print("Crawl finished......")
else:
# 爬取下一页
self.page += 1
return self.GetPage()

# 函数d主要是用于:判断是否提取的数据(因为部分城市有些字段数据是缺失的);
# 没有的话追加空值,以保证程序正常进行,数据不会发现错乱
def d(self,data):
if len(data)==0:
return ''
else:
return data[0]

# 把数据转换为sql语句,并将记录插入到数据库中
def write_sql(self,data):

d = ('http://www.mafengwo.cn' + data["home_url"].encode('utf8'),
data["home_img"].encode('utf8'),
data["cnname"].encode('utf8'),
data["enname"].encode('utf8'),
data["visit_nums"].encode('utf8'),
data["detail"].encode('utf8')
)
sql = 'INSERT INTO Mafengwo_db (home_url,home_img,cnname,enname,visit_nums,detail) ' \
'VALUES ("%s", "%s", "%s", "%s", "%s", "%s");' % d

try:
self.con.execute(sql)
print sql
except:
pass

if __name__ == '__main__':
# 创建数据库连接
db = MySQLdb.connect("localhost", "root", "root", "spider", charset='utf8') con = db.cursor()

Mafengwo = MafengwoSpider(con)
Mafengwo.GetPage()

# 程序结束,关闭连接
db.close()

创建用于存储数据的数据库sql语句

1
2
3
4
5
6
7
8
9
10
CREATE TABLE `mafengwo_db` (
`id` mediumint(8) NOT NULL AUTO_INCREMENT COMMENT '自增ID',
`cnname` varchar(25) DEFAULT NULL COMMENT '城市中文名',
`enname` varchar(25) DEFAULT NULL COMMENT '城市英文名',
`home_url` varchar(225) DEFAULT NULL COMMENT '主页url地址',
`home_img` varchar(225) DEFAULT NULL COMMENT '主页图片url',
`visit_nums` mediumint(8) DEFAULT NULL COMMENT '去过的人数',
`detail` text COMMENT '关于这个旅游城市描述',
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC COMMENT='中国旅游热门城市---来源马蜂窝网';


等待爬取结束,查看数据库,爬取了2500+记录



文章目录
,