Python爬虫马蜂窝结伴信息

最近在做旅游攻略,通过马蜂窝找相应的结伴信息,在马蜂窝网页版上面找对应结伴信息非常困难,刷选相关信息做的非常的不友好,要自己一个个页面点击才能找到对应信息,而且没有对应的条件刷选按钮。还有一个问题就是,找大西北结伴信息中很多车队的帖子和跟帖,这样就更加妨碍我寻找对应信息的。后面想快速找到对应信息,于是有了爬虫马蜂窝结伴的信息想法。
打开马蜂窝结伴首页:http://www.mafengwo.cn/together/ 刷选“拉萨”和“一个月内”等条件,然后刷选到对应的页面信息,选择翻页发现ip地址并没有改变,由此可以知道马蜂窝结伴页的页面是动态网页来的,在谷歌浏览器打开网页,按“F12”进入chrome浏览器的开发工具,点击“Network”->XHR(有时候是JS),然后我们点击上面的页面跳转栏的“2”跳转到第二页,然后我们可以看到开发工具左边的框里出现了一个新的请求,即左下图的最下面那一行(蓝色那条),我们用鼠标点击它,就可以在右边显示出该请求的headers的相关信息。在Headers中我们可以知道:Requests URL就是该网页真正请求的URL,而且由Request Method可以知道这是一个post请求,而下面的Request Headers就是该请求所需要设置的headers参数。因为这是一个post请求,所以我们要查看一下post请求提交了那些数据,所以我们可以在右边的Headers中继续往下拉来查看。
Python爬虫马蜂窝结伴信息_第1张图片
Python爬虫马蜂窝结伴信息_第2张图片

所以由上图的Query String Parameters我们可以知道,post请求上传了几个关键的数据:flag、offset、mddid、timeflag和timestart,
timeFlag就是 “热门结伴、最新发表、即将出发”中一个,flag=3就是热门结伴,默认为热门结伴;
Offset就是对应页面的偏移页面,翻页就是通过这个参数;
Mddid:目的地编码,现在拉萨是10442;
所以根据其中一个网址http://www.mafengwo.cn/together/travel/more?flag=3&offset=1&mddid=10442&timeFlag=3×tart=,可以猜测结伴网页构成为:http://www.mafengwo.cn/together/travel/more? 加上参数:flag=3&offset=1&mddid=10442&timeFlag=3×tart=

#获取总共有多少页
def get_page(url):
    response=urllib.request.urlopen(url).read()
    response=json.loads(response.decode("utf-8").encode('GBK'))
    total=response['data']['total']

    page=int(total/12)+1
    print ("page:",page)
    return page

获取有多少页面后通过构造对应的动态网址然后获取页面详细信息,针对页面明细信息,获取到发送结伴人的基本信息和结伴描述,后面还有报名的用户列表、关注的用户列表、评论的用户和评论的明细,最后将结果保存在excel中。

在处理解释页面明细中,使用了BeautifulSoup和正则进行处理,关注、报名和评论等列表等处理成excel能够存储的格式。
另外还有一个问题,在测试的时候,没有使用代理也没有对爬虫速度进行限制,爬到一半就被马蜂窝禁掉了。后续持续优化添加代理IP进行优化。
下面为爬虫的完整代码:



#######################################################
import xlrd
import xlwt
import xlsxwriter
import requests
import re
import json
import urllib.request
from lxml import etree
from bs4 import BeautifulSoup
from openpyxl import workbook  # 写入Excel表所用

#获取总共有多少页
def get_page(url):
    response=urllib.request.urlopen(url).read()
    response=json.loads(response.decode("utf-8").encode('GBK'))
    total=response['data']['total']

    page=int(total/12)+1
    print ("page:",page)
    return page

	
#循环爬取页数
def get_list(page):
    for i in range(0,page):
        url='http://www.mafengwo.cn/together/travel/more?'+flag+'&'+'offset='+str(i)+'&'+mddid+'&'+'timeFlag=3×tart='
        get_matehtml(url) 
        time.sleep(8)
        print ("#"*20)
        print ("i,url:",i,url)

		

#获取链接网址
def get_matehtml(url):
    response=json.loads(urllib.request.urlopen(url).read().decode("utf-8").encode('GBK'))
    html=response['data']['html']
    pat1='a href=\"(.*?)" target=\"_blank\">'
    rst1 = re.compile(pat1).findall(html)
    i=1
    for html in rst1:
        print ("get_matehtml:",'http://www.mafengwo.cn'+html)
        get_detail('http://www.mafengwo.cn'+html)

	
#获取每个结伴明细信息
def get_detail(html):
    global togetherlist
    response=urllib.request.urlopen(html).read().decode("utf-8")
    #获取标题
    pat1='(.*?)'
    title=re.compile('(.*?)').findall(response)[0]
    print("title:",title)
    see=re.compile('(.*?)人').findall(response)[0]
    sign=re.compile('(.*?)人').findall(response)[1]
    follow=re.compile('(.*?)人').findall(response)[2]
    soup = BeautifulSoup(urllib.request.urlopen(html).read(), 'lxml')
    title=soup.title.get_text()
    gooff=re.compile('出发时间:(.*?)').findall(response)[0]
    days=re.compile('大约:(.*?)').findall(response)[0]
    des=re.compile('目的地:(.*?)').findall(response)[0]
    fro=re.compile('出发地:(.*?)').findall(response)[0]
    num=re.compile('希望人数:(.*?)').findall(response)[0]
    enrollment=re.compile('(.*?)').findall(response)[0]
    female=re.compile('MM(.*?) GG(.*?) 

参考资料:

Python爬虫爬取动态网页

https://blog.csdn.net/guanmaoning/article/details/80158554

你可能感兴趣的:(机器学习)