Python爬虫时翻页等操作URL不会改变的解决办法--以爬取携程景点点评信息为例

一、需求:

      需要爬取携程的五四广场景点主页的用户点评信息。

二、爬虫时可能遇到的问题:

评论信息虽然可以在该页的源代码中获取到:

但是存在许多问题,例如:

1、评论翻页、修改评论排序方式(智能排序、有用数排序、按时间排序)并不会改变当前页的URL。

2、使用Fiddler等的抓包工具,虽然能够找到该网页用来进行评论数据传输的文件AsynCommentView的URL,但是发现翻页以及修改评论排序方式同样不会改变URL。

3、得出结论,评论信息是“动态加载的”。

三、问题分析:

1、观察景点页面的源代码,注意到关键代码:

        这行代码直接说明了,该网页的评论信息是通过POST服务的形式,向评论数据传输文件AsynCommentView的URL发送POST请求,然后获取返回的评论数据。

2、通过Chrome内核浏览器的F12工具,切换到network查看一下传输的内容,首先清空内容避免干扰,然后点击翻页或者切换排序方式,切换到Headers我们可以看到:

     发送的请求信息无处遁形~

4、那么问题来了,请求的内容参数该如何设置呢?

(1)order以及pagenow:顾名思义,是排序方式(按时间:1 ,有用数:2,智能:3)以及当前页码。

(2)star、tourist:测试发现使用0.0即可。

(3)poiID、districtId、districtEName、resourceId、resourcetype:无法轻易判断,但是通过观察网页源代码:

    发现源代码帮了大忙,他会把默认的参数储存,可以通过爬取这些参数来进行填充。

3、因此可以初步思考爬虫的解决思路:即使用自动模拟HTTP请求来解决,具体可参考我的另一篇博客:

        Python数据爬虫学习笔记(5)自动模拟HTTP请求

三、编写代码:

import re
import urllib.request
import urllib.parse

#模拟浏览器
headers=("User-Agent","Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.26 Safari/537.36 Core/1.63.6726.400 QQBrowser/10.2.2265.400")
opener=urllib.request.build_opener()
opener.addheaders=[headers]
urllib.request.install_opener(opener)

#设置URL为当前景点页面并获取内容
baseUrl="http://you.ctrip.com/sight/Qingdao5/5326.html#ctm_ref=www_hp_bs_lst"
pagedata=urllib.request.urlopen(baseUrl).read().decode("utf-8","ignore")

#爬取页面中的POST参数信息并进行处理
poiIDPat='var poiid = "(.*?)"'
districtIdPat='var districtid = "(.*?)"'
districtENamePat='var districtename = "(.*?)"'
resourceIdPat='var resourceid = "(.*?)"'
resourcetypePat='var resourcetype = "(.*?)"'

poiID=int(re.compile(poiIDPat,re.S).findall(pagedata)[0])
districtId=int(re.compile(districtIdPat,re.S).findall(pagedata)[0])
districtEName=re.compile(districtENamePat,re.S).findall(pagedata)[0]
resourceId=int(re.compile(resourceIdPat,re.S).findall(pagedata)[0])
resourcetype=int(re.compile(resourcetypePat,re.S).findall(pagedata)[0])
order=1 #排序方式,此处设置为按时间排序
star=0.0
tourist=0.0

#设定数据传输文件的URL,当Post网址无法轻易找到时,可以使用抓包分析
url="http://you.ctrip.com/destinationsite/TTDSecond/SharedView/AsynCommentView"
comments=[]#存储所有评论的列表
#以爬取评论前30页为例
for i in range(1,31):
    #设定Post的值
    mydata=urllib.parse.urlencode({
        "poiID":poiID,
        "districtId":districtId,
        "districtEName":districtEName,
        "pagenow":i,
        "order":order,
        "star":star,
        "tourist":tourist,
        "resourceId":resourceId,
        "resourcetype":resourcetype
    }).encode("utf-8")
    #发送POST请求进行爬取
    req=urllib.request.Request(url,mydata)
    commentdata=urllib.request.urlopen(req).read().decode("utf-8","ignore")
    commentPat='<span class="heightbox">(.*?)</span>'
    #获得当前页评论并存储
    comment=re.compile(commentPat,re.S).findall(pagedata)
    comments.extend(comment)
    
#写入txt文件
file_handle=open('E:/comment.txt',mode='w')
for j in range(0,len(comments)):
    text = "评论内容:"+comments[j] + '\n\n'  
    file_handle.write(text)
file_handle.close()

四、爬取结果:

猜你喜欢

转载自blog.csdn.net/Smart3S/article/details/83472655