以上海旅游景点数据为例
参考网址:上海旅游景点
爬虫逻辑:【分页网页url采集】-【数据采集】
还是按照爬虫逻辑二进行获取数据
函数1:get_urls(city,n) → 【分页网页url采集】
city:城市对应的编码
n:页数参数
结果:得到一个分页网页的list
函数2:get_data(ui,d_h,d_c) → 【数据采集】
ui:数据信息网页
d_h:user-agent信息
d_c:cookies信息
结果:得到数据的list,每条数据用dict存储
采集字段
景点名称、评分、排名、简介、攻略提到数量、点评数量、多少比例驴友来过、经纬度
要求
采集200条数据
20页【分页网页url采集】- 每页10条数据
结果保存为dataframe,并做基本数据清洗
经度、纬度、攻略提到数量、点评数量 → 数据格式转换
评分
排名
多少比例驴友来过
查找url规律
去哪儿网上海旅游景点前2-4页的url如下
u2 = https://travel.qunar.com/p-cs-shanghai-jingdian-1-2 u3 = https://travel.qunar.com/p-cs-shanghai-jingdian-1-3 u4 = https://travel.qunar.com/p-cs-shanghai-jingdian-1-4 ......
由上可以推知,url规律是将网址最后面的数值进行修改,查看每页的数据,可知一个url里面包含了10条数据,因此就可以构建前20页全部url,第一页的规律一般默认是数字从0开始的(但是这里的是从1开始的)
urllst = [] for i in range(20): ui = "https://travel.qunar.com/p-cs-shanghai-jingdian-1-{}".format(i+1) urllst.append(ui)
由此,前20个url的信息就已经全部构造完成
导入相关库和封装第一个函数
import requests from bs4 import BeautifulSoup import pandas as pd def get_url(n): ''' 【分页网址url采集】函数 n:页数参数 结果:得到一个分页网页的list ''' lst = [] for i in range(n): ui = "https://travel.qunar.com/p-cs-shanghai-jingdian-1-{}".format(i+1) lst.append(ui) return lst print(get_url(10))
输出的结果为:
设置headers和cookies
由于不是在爬豆瓣的数据(cookies改变了),需要登录一下去哪儿网,没有用户的可以注册一下,然后按照之前的步骤获取headers和cookies
将headers和cookies以字典的方式存储
dic_heders = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36' } dic_cookies = {
} cookies = 'QN1=dXrgj14+tmYQhFxKE9ekAg==; QN205=organic; QN277=organic; QN269=506F28C14A7611EAA0BEFA163E; _i=RBTKSRDqFhTQT5KRlx-P1H78agxx; fid=7cc3c3d9-3f6c-45e1-8cef-3384cd5da577; Hm_lvt_c56a2baadeafc=,; viewpoi=|; viewdist=-7; uld=1--8-|1--1-; QN267=d5aedfc8; Hm_lpvt_c56a2baadeafc=; QN25=cb06bfbd-d687-4072-98c5-73266b637a6a-9f992f90; QN42=nvxp8441; _q=U.qunar_lbs_; _t=; csrfToken=oXYBnhSoGAGxggRkzmAjbxxGrpgsjUqQ; _s=s_ZBWFJO3EEGZISWS35EBIS5NQYA; _v=YTRjW_H5L47nGNVabvTLt1mlh7j8R7t4UNDVRrJUz0wScfLMWgSvkwQbzMLHlFbsvTU-2kJrBK74NUyOi3MX_3obY94Hhhugt8bv8ILxwsWDv4s_ANNiM8qRdg6HlBrrCEnGYr8lxS9uv78zDCNKz9pFbN8JPYy-AKJP6xILIsT7; _vi=4ONQzvfOOhwJECN5R-4rfWZDzlQ5-qv2xi_jsp1INPEpy9iKHa5gV0gHc35fDfTDe3TjcKteU7ZWk1vd6MsIqTfXYyUh3gTwZJ_9z3PEpkXZReeeIjaVE4HwLTkOATLIzIxg92s-QCWKE1RdNlaZsxPnfN7NHPGAZz5rsmxvpNDY; QN44=qunar_lbs_; QN48=tc_a7fe4861b2d918df_fc8_67ab; QN271=1749d44a-1a11-4886-be27-c3e3bfdadb0c' cookies_lst = cookies.split("; ") for i in cookies_lst: dic_cookies[i.split("=")[0]] = i.split("=")[1]
请求网页信息和网页解析
urllst_1 = get_url(10) u1 = urllst_1[0] r1 = requests.get(u1, headers= dic_heders, cookies = dic_cookies) print(r1)
输出的结果为:
说明网址可以正常访问,下面就进行网页的解析,在浏览器中该页面右键检查,可以发现,整个旅游景点的信息都包含在【ul class=“list_item clrfix”】的标签里面,其中每条数据都在【li】标签下,而且每条标签上还有这个景点的经纬度信息(data-lat=“31.”,data-lng=“121.”)
因此,可以选择获取某一个旅游景点数据进行试错(一般是选取第一个素)
urllst_1 = get_url(10) u1 = urllst_1[0] r1 = requests.get(u1, headers= dic_heders, cookies = dic_cookies) soup_i = BeautifulSoup(r1.text,'lxml') ul = soup_i.find("ul",class_="list_item clrfix") lis = ul.find_all('li') li_0 = lis[0] print(li_0)
输出的结果如下:(可以正常的获取该标签下的旅游景点的信息,下一步就是解析具体标签获取相应的数据)
已经可以获取每个旅游景点的对应标签的全部数据,那么接下来就可以有针对性的获取我们所需要的数据,依次找到各个数据对应的标签
1)景点名称
2)攻略数量
3)评分
4)简介
5)排名
6)经纬度
7)点评数量
8)多少驴友来过
至此所需数据所对应的标签全部找到,但是需要注意,在获取‘排名’和‘多少驴友来过’这两个标签信息时候,不能直接定位到最后一级的标签(也就是【‘span’,class_=“sum”】),因为这两个数据对应的最后一级标签是一样的,所以要先找到它们的上一级标签,在获取相应的数据
获取所有数据的代码如下:(注意‘排名’数据的获取,有部分是空值,所以直接进行母标签的获取,不能进行子标签的获取)
dic = {
} dic['景点名称'] = li_0.find('span',class_="cn_tit").text dic['攻略数量'] = li_0.find('div',class_="strategy_sum").text dic['评分'] = li_0.find('span',class_="total_star").span['style'] dic['简介'] = li_0.find('div',class_="desbox").text dic['排名'] = li_0.find('span',class_="ranking_sum").text dic['经度'] = li_0['data-lng'] dic['纬度'] = li_0['data-lat'] dic['点评数量'] = li_0.find('div',class_="comment_sum").text dic['多少驴友来过'] = li_0.find('span',class_="comment_sum").span.text print(dic)
输出的结果为:
核对一下,首页的第一条旅游数据和输出的结果数据,可以发现结果是一致的
封装第二个函数
第一条旅游景点数据试错完成后就可以进行遍历数据输出,并封装成为函数,方便调用
def get_data(ui,d_h,d_c): ''' 【数据采集】 ui:数据信息网页 d_h:user-agent信息 d_c:cookies信息 结果:得到数据的list,每条数据用dict存储 ''' ri = requests.get(ui, headers= dic_heders, cookies = dic_cookies) soup_i = BeautifulSoup(ri.text,'lxml') ul = soup_i.find("ul",class_="list_item clrfix") lis = ul.find_all('li') lst = [] for li in lis: dic = {
} dic['景点名称'] = li.find('span',class_="cn_tit").text dic['攻略数量'] = li.find('div',class_="strategy_sum").text dic['评分'] = li.find('span',class_="total_star").span['style'] dic['简介'] = li.find('div',class_="desbox").text dic['排名'] = li.find('span',class_="ranking_sum").text dic['经度'] = li['data-lng'] dic['纬度'] = li['data-lat'] dic['点评数量'] = li.find('div',class_="comment_sum").text dic['多少驴友来过'] = li.find('span',class_="comment_sum").span.text lst.append(dic) return lst urllst_1 = get_url(10) u1 = urllst_1[0] print(get_data(u1,dic_heders,dic_cookies))
输出的结果为:
对应这两个旅游景点的原页面如下:(可以看出最终获取的数据是和原网页的数据是匹配的)
接着就是进行全部数据的输出与存储,再此过程中,还要进行错误异常的处理
datalst = [] errorlst =[] for u in get_url(20): try: datalst.extend(get_data(u,dic_heders,dic_cookies)) print('数据采集成功,共采集数据{}条'.format(len(datalst))) except: errorlst.append(u) print('数据采集失败,网址为:',u)
输出的结果为:
数据清洗
数据清洗在spyder里面进行,避免爬虫代码的反复运行
df = pd.DataFrame(datalst) df['经度'] = df['经度'].astype('float') df['纬度'] = df['纬度'].astype('float') df['点评数量'] = df['点评数量'].astype('int') df['攻略数量'] = df['攻略数量'].astype('int') df['评分'] = df['评分'].str.split(":").str[-1].str.replace("%","").astype("float") df['多少驴友来过'] = df['多少驴友来过'].str.replace("%","").astype('float')/100 df['排名'] = df[df['排名']!=""]['排名'].str.split("第").str[-1].astype('int') df.to_excel('去哪儿网数据爬取.xlsx',index = False)
至此去哪儿网景点数据采集项目的全过程就已经解析完毕了,下面是全部的代码和输出结果
全部代码和输出结果
import requests from bs4 import BeautifulSoup import pandas as pd def get_url(n): ''' 【分页网址url采集】函数 n:页数参数 结果:得到一个分页网页的list ''' lst = [] for i in range(n): ui = "https://travel.qunar.com/p-cs-shanghai-jingdian-1-{}".format(i+1) lst.append(ui) return lst def get_data(ui,d_h,d_c): ''' 【数据采集】 ui:数据信息网页 d_h:user-agent信息 d_c:cookies信息 结果:得到数据的list,每条数据用dict存储 ''' ri = requests.get(ui, headers= dic_heders, cookies = dic_cookies) soup_i = BeautifulSoup(ri.text,'lxml') ul = soup_i.find("ul",class_="list_item clrfix") lis = ul.find_all('li') lst = [] for li in lis: dic = {
} dic['景点名称'] = li.find('span',class_="cn_tit").text dic['攻略数量'] = li.find('div',class_="strategy_sum").text dic['评分'] = li.find('span',class_="total_star").span['style'] dic['简介'] = li.find('div',class_="desbox").text dic['排名'] = li.find('span',class_="ranking_sum").text dic['经度'] = li['data-lng'] dic['纬度'] = li['data-lat'] dic['点评数量'] = li.find('div',class_="comment_sum").text dic['多少驴友来过'] = li.find('span',class_="comment_sum").span.text lst.append(dic) return lst if __name__ == "__main__": dic_heders = {
'User-Agent' : 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36' } dic_cookies = {
} cookies = 'QN1=dXrgj14+tmYQhFxKE9ekAg==; QN205=organic; QN277=organic; QN269=506F28C14A7611EAA0BEFA163E; _i=RBTKSRDqFhTQT5KRlx-P1H78agxx; fid=7cc3c3d9-3f6c-45e1-8cef-3384cd5da577; Hm_lvt_c56a2baadeafc=,; viewpoi=|; viewdist=-7; uld=1--8-|1--1-; QN267=d5aedfc8; Hm_lpvt_c56a2baadeafc=; QN25=cb06bfbd-d687-4072-98c5-73266b637a6a-9f992f90; QN42=nvxp8441; _q=U.qunar_lbs_; _t=; csrfToken=oXYBnhSoGAGxggRkzmAjbxxGrpgsjUqQ; _s=s_ZBWFJO3EEGZISWS35EBIS5NQYA; _v=YTRjW_H5L47nGNVabvTLt1mlh7j8R7t4UNDVRrJUz0wScfLMWgSvkwQbzMLHlFbsvTU-2kJrBK74NUyOi3MX_3obY94Hhhugt8bv8ILxwsWDv4s_ANNiM8qRdg6HlBrrCEnGYr8lxS9uv78zDCNKz9pFbN8JPYy-AKJP6xILIsT7; _vi=4ONQzvfOOhwJECN5R-4rfWZDzlQ5-qv2xi_jsp1INPEpy9iKHa5gV0gHc35fDfTDe3TjcKteU7ZWk1vd6MsIqTfXYyUh3gTwZJ_9z3PEpkXZReeeIjaVE4HwLTkOATLIzIxg92s-QCWKE1RdNlaZsxPnfN7NHPGAZz5rsmxvpNDY; QN44=qunar_lbs_; QN48=tc_a7fe4861b2d918df_fc8_67ab; QN271=1749d44a-1a11-4886-be27-c3e3bfdadb0c' cookies_lst = cookies.split("; ") for i in cookies_lst: dic_cookies[i.split("=")[0]] = i.split("=")[1] datalst = [] errorlst =[] for u in get_url(20): try: datalst.extend(get_data(u,dic_heders,dic_cookies)) print('数据采集成功,共采集数据{}条'.format(len(datalst))) except: errorlst.append(u) print('数据采集失败,网址为:',u) df = pd.DataFrame(datalst) df['经度'] = df['经度'].astype('float') df['纬度'] = df['纬度'].astype('float') df['点评数量'] = df['点评数量'].astype('int') df['攻略数量'] = df['攻略数量'].astype('int') df['评分'] = df['评分'].str.split(":").str[-1].str.replace("%","").astype("float") df['多少驴友来过'] = df['多少驴友来过'].str.replace("%","").astype('float')/100 df['排名'] = df[df['排名']!=""]['排名'].str.split("第").str[-1].astype('int') df.to_excel('去哪儿网数据爬取.xlsx',index = False)
输出的结果为:
去哪儿网数据爬取.xlsx文件中的内容如下:(可以看出最后将数字数据全都转变成了数值型,而非文本型)
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ji-chu/82710.html