天天看点

携程旅游网与马蜂窝游客记录爬取

前言:这是我学习Python爬虫以来,第一次使用python进行大规模的进行数据挖掘。邀请我加入她们科研项目的是工商学院的彭老师,做一个关于避暑旅游的课题。当他们需要获取携程旅游笔记时,由于文章的内容太多,思路也没有考虑好,无法使用数据采集器把笔记放入Excel。于是找到了我们信息学院寻求方法帮助,我的辅导员老师就向她推荐了我。终于有机会进行大型的项目实战了,非常幸运能参与这次的项目。但也由于平时比较繁忙,真正开发的时间并不是很多,通常都是课余时间做的。

第一次项目交接

她安排她的学生黄超来与我进行交接,告诉我,他们的需求。以前数据的采集就是他负责的,所以需求还是非常清楚的。他打电话与我沟通,说需要把旅游的笔记放进Excel做数据分析,我不是很理解,对于这些不规则的文本,最好的方式应该是放进txt文本才方便呀,经过一些沟通后,确定第二天见面谈。我需要在周末上双学位的课程,10月13号下午下课后就在我们上课的教室讨论,指出我需要爬取的内容。

当天也相当于交流学习,我从未做过这方面的实战。听他的要求后,最理想的方式是把它文字保存在txt文本,并不是Excel,初步达成共识。

第一次爬取:携程网,游客游记,关键词“避暑旅游”,不限时间,初次搜索出4398条

携程旅游网与马蜂窝游客记录爬取

由于数量太大,更改关键词为“避暑”,时间为1年内,游记,共找到800篇,作为这次爬取的目标。由于是初次做这样的工作,变弄便沟通,花了3多小时的时间才完成初步的工作,实现思路如下:

实现思路第一步:爬取一篇文本做测试

1.1.1、获取单篇文章游客笔记文本

携程旅游网与马蜂窝游客记录爬取

通过分析HTML发现,我所需要获取的文字都在

class="ctd_content"

这个标签类,直接通过BeautifulSoup的find模块找到所有的文本就可以了;

携程旅游网与马蜂窝游客记录爬取

运行结果如下:

携程旅游网与马蜂窝游客记录爬取

1.1.2、保存获取的内容到txt文本

txt = str(txt)#把获取的内容转换为字符,建议使用
filename = 'D:write_data.txt'
with open(filename,'w',encoding='utf-8') as f: # 如果filename不存在会自动创建, 'w'表示写数据,写之前会清空文件中的原有数据!
    f.write(txt)
    f.close()
           

txt截屏:

携程旅游网与马蜂窝游客记录爬取

经验:为什么要把获取到的内容转化为字符串?

我在写入txt的过程中,发现很多文本会提示类型有有误,转成字符串后就没有报错了。

现在算是成功最主要的一步了,接下来就是爬取所有的文章了。

实现思路第二步:获取所有文本链接

1.2.1、获取一个主页的所有文章链接

import requests
from lxml import etree
url = 'https://you.ctrip.com/searchsite/travels/?query=避暑&isAnswered=&isRecommended=&publishDate=365&PageNo=1'
html = requests.get(url).text
txt = etree.HTML(html)
file = txt.xpath('/html/body/div[2]/div[2]/div[2]/div/div[1]/ul/li')
for t in file:
    href = t.xpath('./dl/dt/a/@href')[0]
    hrefUrl = 'https://you.ctrip.com'+href#把链接补充完整
    print (hrefUrl)
           

获取结果:

携程旅游网与马蜂窝游客记录爬取

注意: 携程网使用的是相对路径,我们需要把获取的链接补充完整,在前面加上“https://you.ctrip.com”,

1.2.1、获取每个主页的链接

携程旅游网与马蜂窝游客记录爬取

1.2.1、获取每个主页的所有文章链接,并添加到数组

为什么要把获取到的链接存在数组,不是直接进行获取它的内容?

1、从数组内遍历出来速度比单独爬取一个会更快

2、减少被反爬的概率,经常访问更容易被识别出爬虫

3、优化逻辑

import requests
from lxml import etree
from bs4 import BeautifulSoup

headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'
}
allUrl = []
for num in range(1,81,1):
    print(num)
    url = 'https://you.ctrip.com/searchsite/travels/?query=避暑&isAnswered=&isRecommended=&publishDate=365&PageNo='+str(num)
    html = requests.get(url).text
    txt = etree.HTML(html)
    file = txt.xpath('/html/body/div[2]/div[2]/div[2]/div/div[1]/ul/li')
    for t in file:
        href = t.xpath('./dl/dt/a/@href')[0]
        hrefUrl = 'https://you.ctrip.com'+href
        allUrl.append(hrefUrl)
           

1.2.1、开始获取所有的文章

import requests
from lxml import etree
from bs4 import BeautifulSoup

headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'
}
k = 0
allUrl = []
for num in range(1,81,1):
    print(num)
    url = 'https://you.ctrip.com/searchsite/travels/?query=避暑&isAnswered=&isRecommended=&publishDate=365&PageNo='+str(num)
    html = requests.get(url).text
    txt = etree.HTML(html)
    file = txt.xpath('/html/body/div[2]/div[2]/div[2]/div/div[1]/ul/li')
    for t in file:
        href = t.xpath('./dl/dt/a/@href')[0]
        hrefUrl = 'https://you.ctrip.com'+href
        allUrl.append(hrefUrl)
        
for useUrl in allUrl:
    k = k + 1
    print ("正在获取第%s篇"%k)
    print (useUrl)
    html = requests.get(url = useUrl,headers=headers).text
    soup = BeautifulSoup(html, "html.parser")
    t = soup.find(attrs={"class": "ctd_content"})
    txt = t.get_text().replace("\n","")
    txt = str(txt)
    filename = 'G:write_data.txt'
    with open(filename,'a',encoding='utf-8') as f: # 如果filename不存在会自动创建, 'w'表示写数据,写之前会清空文件中的原有数据!
        f.write(txt)
        f.close()
print ("获取完毕!")
           

幸运点:

1、还好这次的运气比较好,没有遇见服务器请求失败的情况,一气呵成

2、网页结构统一,没有出现结构异常而报错

更具他留下来的要求,还需要爬取携程网的问答模块,马蜂窝的三个模块,分别是关键词为“避暑”的游记,攻略和问答。

第二天,我在上课的时间完成了对携程网问答模块的爬取,并把完成的文本发给他先做研究。晚上的时候,他告诉我说,他们老师想见我,和我仔细的交流一下。

第二次项目交接

周二,我白天要上班到16:30,我晚上还要上三节课,通过电话约定16:40去找她,简单的交流一下。这次说是项目交接,还不如说叫做聊天吧,彭老师告诉我她们在做什么项目,并且完成的进度,对技术人员的需求。接下来我就是向她展示了一下我爬取数据的思路,方便她在写文稿的时候有相关的思路,并且简单的确认了一下接下来数据的获取。

在她看来,会一门别人不会的技术,在做学术上是有很大优势的。而我所掌握的网络爬虫就是一门不错的技术,希望我能做好这门技术,给讲了很多考研和做学术的事。多参与这类项目的开发,并发表相关的论文,对我考研是有很大帮助的,但对于考研的事情,我并没有明确自己的目标。

经过交谈,她也想学习Python爬虫,并让我有时间的时候指导一下学习,后来帮她安装好了学习Python的编译,给了一些入门基础教程,让她先了解一下基础,以后再教授爬虫实战和对付反爬等相关工作。

当天晚上,我开始对马蜂窝的数据进行了爬取实战。

最近有人使用数据采集器爬了马蜂窝的1800万数据就刷爆了网络,惊动了互联网界和投资界,背后的数据团队也因此爆红。所以它的数据又重新做好保护措施,我这次爬取它还是花了一些时间来研究它的。请求到它的源码后,发现我需要的数据都没有在其中,这就有点麻烦了,只能使用其他的办法了。经过仔细的查看后,我发现它的数据全部都是动态加载的,你看到哪里,它就加载到哪里,建立这个思维后,我开始使用selenium搞自动化,但是这个的效率就要慢很多了,还好不负努力,终于把它解决了,花了一节课的时间运行代码,爬取了所有的游记,共计46篇,速度已经慢得难受了,还好是上课时间,听了一节课,不影响我时间的使用。

2.1.1、获取主页的所有文章链接,保存到数组

import requests
from lxml import etree
from bs4 import BeautifulSoup
filename = 'G:马蜂窝游记笔记文本.txt'
noteBook = 'G:马蜂窝游记笔记评论.txt'

url = 'http://www.mafengwo.cn/search/q.php?q=%E9%81%BF%E6%9A%91&t=notes&seid=D8276190-E622-4B11-A1B6-DF09CF22DD76&mxid=&mid=&mname=&kt=1'
headers = {
    'Referer': 'http://www.mafengwo.cn/search/q.php?q=%E9%81%BF%E6%9A%91&t=notes&seid=D8276190-E622-4B11-A1B6-DF09CF22DD76&mxid=&mid=&mname=&kt=1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'
}
allUrl = []
htmlUrl = requests.get(url,headers = headers).text
txtUrl = etree.HTML(htmlUrl)
file = txtUrl.xpath('//*[@id="_j_search_result_left"]/div/div/ul/li')
for t in file:
    hrefUrl = t.xpath('./div/div[2]/h3/a/@href')[0]
    allUrl.append(hrefUrl)
 	print (hrefUrl)
print(len(allUrl))
           

部分截屏,一共获取46条链接

携程旅游网与马蜂窝游客记录爬取

2.1.2、打开文章,下拉加载数据

使用selenium对js进行操作

for t in range(1000,310000,1000):#第一次下拉1000像素,第二次要大于1000,相当于从零算起,310000是它的总像素
        time.sleep(0.1)#延时,模拟人为加载
        js=f"document.documentElement.scrollTop={t}"#下拉加载
        driver.execute_script(js)
           

2.1.3、加载数据完毕,获取HTML,并关闭浏览器

由于页面太多,使用浏览器的页面后要关闭浏览器,减少电脑CPU的消耗,也是桌面整洁

source = driver.page_source#获取源码
    driver.close()#关闭浏览器
           

2.1.4、提取作者笔记和评论

# 提取作者笔记
    soup = BeautifulSoup(source, "html.parser")
    note = soup.find(attrs={"class": "_j_content_box"}).get_text()
    note = note.replace("\n","")
    note = str(note)
           
#提取笔记评论
    for usrAnswer in soup.find_all(attrs={"class": "mfw-cmt _j_reply_item"}):
        answer = usrAnswer.find(attrs={"class": "_j_reply_content"}).get_text()
        answer = str(answer)
           

2.1.5、分开保存笔记和评论

分开保存的目的主要是为了方便研究,她们并没有提要求,到这样做比较保险。

# 保存作者笔记
    with open(filename,'a',encoding='utf-8') as f: # 如果filename不存在会自动创建, 'w'表示写数据,写之前会清空文件中的原有数据!
        f.write(note+"\n")
        f.close()
           
#保存笔记评论
        with open(noteBook,'a',encoding='utf-8') as g: # 如果filename不存在会自动创建, 'w'表示写数据,写之前会清空文件中的原有数据!
            g.write(answer+"\n")
            g.close()
           

2.1.6、大功告成,开始批量爬取

from selenium import webdriver
import time
import requests
from lxml import etree
from bs4 import BeautifulSoup

filename = 'G:马蜂窝游记笔记文本.txt'
noteBook = 'G:马蜂窝游记笔记评论.txt'
url = 'http://www.mafengwo.cn/search/q.php?q=%E9%81%BF%E6%9A%91&t=notes&seid=D8276190-E622-4B11-A1B6-DF09CF22DD76&mxid=&mid=&mname=&kt=1'
headers = {
    'Referer': 'http://www.mafengwo.cn/search/q.php?q=%E9%81%BF%E6%9A%91&t=notes&seid=D8276190-E622-4B11-A1B6-DF09CF22DD76&mxid=&mid=&mname=&kt=1',
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'
}
allUrl = []
htmlUrl = requests.get(url,headers = headers).text
txtUrl = etree.HTML(htmlUrl)
file = txtUrl.xpath('//*[@id="_j_search_result_left"]/div/div/ul/li')
for t in file:
    hrefUrl = t.xpath('./div/div[2]/h3/a/@href')[0]
    allUrl.append(hrefUrl)
for urlUser in allUrl:
    print("正在爬取:",urlUser)
    driver = webdriver.Chrome('D:\\Software\\chromedriver.exe')
    driver.get(urlUser)#打开马蜂窝
    driver.implicitly_wait(6)#等待加载六秒
    time.sleep(6)
    for t in range(1000,310000,1000):#第一次下拉1000像素,第二次要大于1000,相当于从零算起,310000是它的总像素
        time.sleep(0.1)#延时,模拟人为加载
        js=f"document.documentElement.scrollTop={t}"#下拉加载
        driver.execute_script(js)
    source = driver.page_source#获取源码
    driver.close()#关闭浏览器
    # 提取作者笔记
    soup = BeautifulSoup(source, "html.parser")
    note = soup.find(attrs={"class": "_j_content_box"}).get_text()
    note = note.replace("\n","")
    note = str(note)
    # 保存作者笔记
    with open(filename,'a',encoding='utf-8') as f: # 如果filename不存在会自动创建, 'w'表示写数据,写之前会清空文件中的原有数据!
        f.write(note+"\n")
        f.close()
    #提取笔记评论
    for usrAnswer in soup.find_all(attrs={"class": "mfw-cmt _j_reply_item"}):
        answer = usrAnswer.find(attrs={"class": "_j_reply_content"}).get_text()
        answer = str(answer)
        #保存笔记评论
        with open(noteBook,'a',encoding='utf-8') as g: # 如果filename不存在会自动创建, 'w'表示写数据,写之前会清空文件中的原有数据!
            g.write(answer+"\n")
            g.close()
            
print ("该页评论已下载完毕!")
           

终于解决了,看以来还行~

携程旅游网与马蜂窝游客记录爬取

2.1.7、更具这样的思路,完成了马蜂窝攻略和问答的爬取

马蜂窝攻略和问答与游记不同的地方在于,它俩的文章比较多,需要翻页,这样使用一个循环就构造好它的链接了,还是比较容易的,圆满完成任务!

携程旅游网与马蜂窝游客记录爬取

第三次项目交接

这次黄超同学重新更改了他的需求,需要重新爬取携程网游记,从以前的一年之内改为时间不限,从800篇变到了9331篇

携程旅游网与马蜂窝游客记录爬取

这样的任务量无疑增加得大了,如果是按照先前的方式运行代码一篇一篇的爬取,在运行顺利的情况下,估计也要花两三个小时吧。所以必须解决速度问题… …

方法一——使用多进程:

我先考虑使用多进程了完成这项工作,分别让它往一个文本中写入数据,多开几个进程。考虑到请求数据库失败,代码报错的问题,我选择使用try函数跳过错误的请求失败的文章,执行后我发现被跳过的文章太多,如果要重新爬取这些文章或减少损失,这是一件不容易的事情。

方法二——分为10段,同时开10个程序:

我需要爬取的文章从1~9331,被我分为了10段执行,并分别把文本写入10个txt文件,哪一个错就重新执行哪一个,10个代码同时执行。

第一个程序:第1~101篇,文件夹:filename = 'G:携程游记之避暑01.txt'
第二个程序:第1001~201篇文件夹:filename = 'G:携程游记之避暑02.txt'
第三个程序:第301~401篇文件夹:filename = 'G:携程游记之避暑03.txt'
.........
第三个程序:第901~9332篇文件夹:filename = 'G:携程游记之避暑10.txt'
           

10个程序分开同时执行:

携程旅游网与马蜂窝游客记录爬取

保存结果:

携程旅游网与马蜂窝游客记录爬取

携程问答爬取:

代码片段其一:

import requests
from bs4 import BeautifulSoup
from lxml import etree
import time
start = time.time()#记录开始时的时间
filename = "G:携程问答之避暑3(1).txt"#保存的文本命名及路径
headers = {
     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'
}
allUrl = []#保存获取的链接
for page in range(1,26,1):
    index = 'https://you.ctrip.com/searchsite/asks/?query=避暑&isAnswered=&isRecommended=&publishDate=&PageNo=%s'%page
    print ("正在获取:",index)
    indexHtml = requests.get(url=index,headers=headers).text
    etreeIndex = etree.HTML(indexHtml)
    liUrls = etreeIndex.xpath('/html/body/div[2]/div[2]/div[2]/div/div[1]/ul/li')
    for li in liUrls:
        href = li.xpath('./dl/dt/a/@href')[0]
        hrefUrl = 'https://you.ctrip.com'+href
        allUrl.append(hrefUrl)
urlNum = len(allUrl)
print ("一共找到%s篇文章需要爬取"%urlNum)
c = 0
for textUrl in allUrl:
    c = c + 1#记录文章篇数
    if c in range(0,4676,10):
        time.sleep(50)#模拟暂停
    print ("正在爬取第%s篇文章,一共有4676篇"%c)
    textHtml = requests.get(url = textUrl,headers = headers).text
    textsoup = BeautifulSoup(textHtml,"html.parser")
    #提取作者笔记标题
    textTitle = textsoup.find(attrs={"class":"ask_title"}).get_text()
    print (textTitle)
    textTitle = str(textTitle)
    with open(filename,'a',encoding='utf-8') as f: # 如果filename不存在会自动创建, 'w'表示写数据,写之前会清空文件中的原有数据!
        f.write(textTitle)
        f.close()
    #提取作者笔记
    titleQuestion = textsoup.find(attrs={"class":"ask_text"}).get_text()
    titleQuestion = str(titleQuestion)
    with open(filename,'a',encoding='utf-8') as f: # 如果filename不存在会自动创建, 'w'表示写数据,写之前会清空文件中的原有数据!
        f.write(titleQuestion)
        f.close()
    #提取评论
    answerBoxs =  textsoup.find_all(attrs={"class":"answer_box cf"})
    for userAnswer in answerBoxs:
        answer = userAnswer.find(attrs={"class":"answer_text"}).get_text()
        answer = str(answer)
        with open(filename,'a',encoding='utf-8') as f: # 如果filename不存在会自动创建, 'w'表示写数据,写之前会清空文件中的原有数据!
            f.write(answer+"\n")
            f.close()
end = time.time()#获取当前时间
useTime = int(end-start)
useTime = useTime/60
print ("本次爬取所有文章一共使用%s分钟"%useTime)
           

6个程序同时进行:

携程旅游网与马蜂窝游客记录爬取

代码运行结果:

携程旅游网与马蜂窝游客记录爬取

文本保存结果:

携程旅游网与马蜂窝游客记录爬取

第四次项目交接

我看见彭老师在群里给她的学生说,文本有空格和换行会影响数据分析,此刻她正在一个一个的删除文本空格和换行。为了节约时间,我就告诉她她文本放入word使用替换功能去掉多余的空格和回车。

携程旅游网与马蜂窝游客记录爬取

但是9千多篇文章还是太多了,她们的分析工具把电脑弄死机几次后,重新决定只要三年的数据,但是携程网上又没有专门筛选三年数据的地方,担心不能实现。

携程旅游网与马蜂窝游客记录爬取

后来我通过提取每个游客的发表时间来提取文章,如果满足2017,2018,2019年,就把它的链接追加在保存链接的数组中,达筛到的目的。

for ettime in  ettimes:
        try:
            pTime = ettime.xpath('./dl/dd[2]/text()')[1]
            pTime = pTime.split("发表于")[1]
            pTime = pTime.split("-")[0]
            href = ettime.xpath('./dl/dt/a/@href')[0]
            hrefUrl = 'https://you.ctrip.com' + href
            if int(pTime) in [2017,2018,2019]:
                print ("符合条件的时间",pTime)
                print (hrefUrl)
                allUrl.append(hrefUrl)
        except:
            pass
           

第一页,1~101页查找结果:

携程旅游网与马蜂窝游客记录爬取

源码如下:

import requests,time
from lxml import etree
from bs4 import BeautifulSoup
start = time.time()
filename = 'G:携程游记之避暑201901.txt'
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'
}
allUrl = []
for page in range(1,101,1):#1,932,1
    indexUrl = 'https://you.ctrip.com/searchsite/travels/?query=避暑&isAnswered=&isRecommended=&publishDate=&PageNo=%s'%page
    print ("正在获取:",indexUrl)
    indexHtml = requests.get(url=indexUrl,headers=headers).text
    etreeIndex = etree.HTML(indexHtml)
    ettimes = etreeIndex.xpath('/html/body/div[2]/div[2]/div[2]/div/div[1]/ul/li')    
    for ettime in  ettimes:
        try:
            pTime = ettime.xpath('./dl/dd[2]/text()')[1]
            pTime = pTime.split("发表于")[1]
            pTime = pTime.split("-")[0]
            href = ettime.xpath('./dl/dt/a/@href')[0]
            hrefUrl = 'https://you.ctrip.com' + href
            if int(pTime) in [2017,2018,2019]:
                print ("符合条件的时间",pTime)
                print (hrefUrl)
                allUrl.append(hrefUrl)
        except:
            pass
urlNum = len(allUrl)
print ("一共找到%s篇文章需要爬取"%urlNum)
c = 0
for textUrl in allUrl:
    c = c + 1
    print ("正在爬取第%s篇文章,一共有%s篇"%(c,urlNum))
    try:
        html = requests.get(url = textUrl,headers=headers).text
        soup = BeautifulSoup(html, "html.parser")
        try:
            title = soup.find(attrs={"class": "title1"}).get_text().replace("\n","").replace(" ","")
        except:
            title = soup.find(attrs={"class": "ctd_head_left"}).get_text().replace("\n","").replace(" ","")
        title = str(title)
        print ("正在爬取:",title)
        t = soup.find(attrs={"class": "ctd_content"})
        txt = t.get_text().replace("\n","").replace(" ","")
        txt = str(txt)
        with open(filename,'a',encoding='utf-8') as f: # 如果filename不存在会自动创建, 'w'表示写数据,写之前会清空文件中的原有数据!
            f.write(title)
            f.write(txt)
            f.close()
    except:
        pass
end = time.time()
useTime = int(end-start)
useTime = useTime/60
print ("该次爬取这%s文章共使用%s分钟"%(urlNum,useTime))
           

第五次项目交接

三年的数据这样存放不好使用分析,文件还是太大了,需要把2017,2018,2019年的数据单独存放,于是又对代码做出了一些更改,完成了最后一次需求!

import requests,time
from lxml import etree
from bs4 import BeautifulSoup
start = time.time()
filename = 'G:携程游记之避暑201910.txt'
headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36'
}
allUrl = []
c = 0
for page in range(901,932,1):#1,932,1
    indexUrl = 'https://you.ctrip.com/searchsite/travels/?query=避暑&isAnswered=&isRecommended=&publishDate=&PageNo=%s'%page
    print ("正在获取:",indexUrl)
    indexHtml = requests.get(url=indexUrl,headers=headers).text
    etreeIndex = etree.HTML(indexHtml)
    ettimes = etreeIndex.xpath('/html/body/div[2]/div[2]/div[2]/div/div[1]/ul/li')
    for ettime in  ettimes:
        try:
            pTime = ettime.xpath('./dl/dd[2]/text()')[1]
            pTime = pTime.split("发表于")[1]
            pTime = pTime.split("-")[0]
            href = ettime.xpath('./dl/dt/a/@href')[0]
            hrefUrl = 'https://you.ctrip.com' + href
            if int(pTime) == 2019:
                print ("符合条件的时间",pTime)
                print (hrefUrl)
                allUrl.append(hrefUrl)
        except:
            pass
urlNum = len(allUrl)
print ("一共找到%s篇文章需要爬取"%urlNum)
for textUrl in allUrl:
    c = c + 1
    print ("正在爬取第%s篇文章,一共有%s篇"%(c,urlNum))
    try:
        html = requests.get(url = textUrl,headers=headers).text
        soup = BeautifulSoup(html, "html.parser")
        try:
            title = soup.find(attrs={"class": "title1"}).get_text().replace("\n","").replace(" ","")
        except:
            title = soup.find(attrs={"class": "ctd_head_left"}).get_text().replace("\n","").replace(" ","")
        title = str(title)
        print ("正在爬取:",title)
        t = soup.find(attrs={"class": "ctd_content"})
        txt = t.get_text().replace("\n","").replace(" ","")
        txt = str(txt)
        with open(filename,'a',encoding='utf-8') as f: # 如果filename不存在会自动创建, 'w'表示写数据,写之前会清空文件中的原有数据!
            f.write(title)
            f.write(txt)
            f.close()
    except:
        pass
end = time.time()
useTime = int(end-start)
useTime = useTime/60
print ("该次爬取这%s文章共使用%s分钟"%(urlNum,useTime))
           

运行结果截屏:

携程旅游网与马蜂窝游客记录爬取

保存文本结果:

携程旅游网与马蜂窝游客记录爬取
携程旅游网与马蜂窝游客记录爬取

很感谢这次的实战机会,通过很多次的需求,让我学会了很多处理数据的方法,提高自己的编程实战能力,帮上一点小忙。