Python网络爬虫实战:爬取携程网酒店评价信息

2023-11-07

这个爬虫是在一个小老弟的委托之下写的。

他需要爬取携程网上的酒店的评价数据,来做一些分词和统计方面的分析,然后来找我帮忙。

爬这个网站的时候也遇到了一些有意思的小麻烦,正好整理一下拿出来跟大家分享一下。

这次爬取过程稍微曲折,各种碰壁,最终成功的过程,还是有点意思。

所以本文我会按照自己当时爬取的思路来讲述,希望能给大家一些思路上的启发。

分析部分略长,如果赶时间可以直接拉到最下面,自取代码。

如果是想学习爬虫的话,最好还是跟着文章的思路走一遍吧。

 

一、明确需求

这位小老弟给我的需求是:

  • 爬取携程网(https://hotels.ctrip.com/)酒店的用户评价数据,具体来讲就是要爬取【上海静安香格里拉大酒店】的评价中,出行类型为【家庭亲子】的用户的评价数据。
  • 评价数据包括:昵称,房型,入住日期,评价日期,评分,评价内容。

要求很简单不是嘛,数据量也不是很大(我看了一下,也才 910 条评价,后来爬取完成之后发现其实只有 750 条左右),根本不够看的。于是,我自作主张,返了个场,在他需求的基础上添加了几条:

  • 酒店不只爬一家了,要爬就爬取【北京市】的所有【四星级以上】的酒店。
  • 评价数据也不止爬【家庭亲子】类型了,要爬就爬所有的评价数据。

 

二、分析目标网站

这里我发现新手在这里一般都有一个共有的误区,就是他们觉得爬虫都是 “通用” 的,一个网站的爬虫拿过来,网址改一下,再随便撺吧撺吧就可以爬另一个网站了。

实际上,每一个网站的爬取都是需要单独进行分析的,你需要找到目标数据是在网页上的什么位置,是通过静态还是动态的方式加载进去的,网站是否有难搞的反爬虫措施,等等,从而来制定自己爬虫的爬取策略。

一般情况下,除非两个网站是极其相似的,或者根本就是用同一个网页模板开发的,这样的话可以套用同一个爬虫来爬,否则,需要针对每个网站的特点去写对应的爬虫。

 

1. 酒店列表爬取

好了,话不多讲,我们先来分析一下目标网站。

首先打开携程网站,目的地选择【北京】,星级选择【四星级】和【五星级】,点击搜索。

此时网址是:https://hotels.ctrip.com/hotel/beijing1#ctm_ref=hod_hp_sb_lst

可以看到网址中只包含了 【北京】 这个信息,什么四星级五星级的筛选条件,并没有体现在 URL 中。但是从结果来看,它又是确实完成了筛选,所以筛选条件的这些参数肯定是包含在请求的某一个位置的。

继续向下看,翻到页尾,发现网站是用这种方式来实现【翻页】功能的。点击【下一页】,跳转到了第 2 页。

回头看一下 URL,居然没有一丝变化,还是:https://hotels.ctrip.com/hotel/beijing1#ctm_ref=hod_hp_sb_lst

到现在基本可以确定一件事儿了,网页中的酒店信息是通过【动态】方式加载进来的。

 

好,我们去抓包看一下,按 F12 召唤出【开发者工具】,切换到【Network】选项卡,然后刷新一下页面。

天哪,瞧我发现了什么!!!

在浏览器加载页面时,我抓到了一个叫【AjaxHotelList.aspx】的网络请求,而它的返回结果,恰恰就是我们页面中展示的酒店列表的信息。

果然,携程网的酒店数据,是通过 Ajax 请求动态地加载的。如果没猜错的话,刚才没找到的【四星级、五星级】筛选条件参数,以及页码的参数,应该就藏在这个 Ajax 请求的参数中吧。

如图,切换到 Headers 选项,拉到最底下(Form Data 里的参数有点多,代表了各种各样的筛选条件,不过我们不关心那些),看到了 star 和 page 两个参数。

 

果然如我所料!

不过不能高兴太早,为了防止网站有什么比较坑爹的反爬机制,最好先写段代码验证一下,看能否按照预期爬到数据。

这里我网络请求用的是 requests 库,数据解析用的是 json 库。

照着浏览器中开发者工具里的 Ajax 请求,把里面的 url,headers,以及 form data 搬过来填这里,发起请求,打印返回结果。

(无关的参数实在太多了,这里简化了一下,只保留了关键的三个参数,cityId,star,和 page)


  
  
  1. import requests
  2. import json
  3. def fetchHotel(city, star, page):
  4. url = "https://hotels.ctrip.com/Domestic/Tool/AjaxHotelList.aspx"
  5. headers = {
  6. 'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
  7. 'Origin': 'https://hotels.ctrip.com',
  8. 'Referer': 'https://hotels.ctrip.com/hotel/beijing1',
  9. 'accept': '*/*',
  10. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
  11. }
  12. formData = {
  13. 'cityId': city,
  14. 'star': star,
  15. 'page': page,
  16. }
  17. # 发起网络请求
  18. r = requests.post(url, data=formData,headers=headers)
  19. r.raise_for_status()
  20. r.encoding = r.apparent_encoding
  21. # 打印 r.text 来看看是否获取到了酒店数据
  22. print(r.text)
  23. fetchHotel( '1', '4,5', 1)

 运行一下,确实出来结果了(虽然输出一堆 “乱七八糟” 的东西,但是从中文字里还是能够看出来,数据取到了)

 OK,这条路走通了,不过既然都写到这儿了,顺手把 json 给解析一下,把数据提取了吧。(免得有的小伙伴不相信)

这里我们提取 酒店名称,酒店ID 打印出来看看。


  
  
  1. import requests
  2. import json
  3. def fetchHotel(city, star, page):
  4. url = "https://hotels.ctrip.com/Domestic/Tool/AjaxHotelList.aspx"
  5. headers = {
  6. 'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
  7. 'Origin': 'https://hotels.ctrip.com',
  8. 'Referer': 'https://hotels.ctrip.com/hotel/beijing1',
  9. 'accept': '*/*',
  10. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
  11. }
  12. formData = {
  13. 'cityId': city,
  14. 'star': star,
  15. 'page': page,
  16. }
  17. # 发起网络请求
  18. r = requests.post(url, data=formData,headers=headers)
  19. r.raise_for_status()
  20. r.encoding = r.apparent_encoding
  21. # 打印 r.text 来看看是否获取到了酒店数据
  22. #print(r.text)
  23. # 解析 json 文件,提取酒店数据
  24. json_data = json.loads(r.text)[ 'hotelPositionJSON']
  25. hotelList = []
  26. for item in json_data:
  27. hotelId = item[ 'id']
  28. hotelList.append(hotelId)
  29. print(item[ 'name'], hotelId)
  30. return hotelList
  31. fetchHotel( '1', '4,5', 1)

运行代码,你看!没错吧,是我们要的酒店列表。

到这里,酒店列表爬取工作,基本就跑通了。


 2. 酒店评论爬取

接下来该研究研究酒店评论该怎么爬取吧。

随便打开一个酒店,进入详情页之后,找到了【酒店点评】部分。

在这里,我们可以找到需要的评论的数据,用户昵称,评分,出游类型,入住时间,评价时间,房型,评价内容等等。

继续往下翻,评论页数同样的方式翻页,而且翻页时候 URL 不变,不用说,又是 Ajax 动态加载咯。

直接 F12 召唤 开发者工具,流程很熟悉了,就讲快一点啦。于是我就抓到了评价数据的包了。

(其实很好找的啦,AjaxHotelCommentList,懂点英语的都能猜到是这个了)

不过它返回的内容格式不是 json 了,而是 html,而且没有排版,格式有点乱。

这个不要紧,去随便找一个在线代码格式化网站(http://tool.oschina.net/codeformat/html),排个版就好了。

解析 json 文件可以用 json 库,解析 HTML 文件用什么呢?我一般用 BeautifulSoup 库,贼拉好用。

这里先不急解析,先写代码验证一下,看看有没有什么坑爹的反爬机制。

 同样的方法,讲 Ajax 请求中的 Url,headers 还有 formdata 里的参数都扣过来,跑一下。


  
  
  1. import requests
  2. def fetchCmts(hotel, page):
  3. url = "https://hotels.ctrip.com/Domestic/tool/AjaxHotelCommentList.aspx?MasterHotelID=469055&hotel=469055&NewOpenCount=0&AutoExpiredCount=0&RecordCount=5420&OpenDate=2013-12-01&card=-1&property=-1&userType=-1&productcode=&keyword=&roomName=&orderBy=2&viewVersion=c&contyped=0&eleven=12488c2f039b057861112f7bc2f1322271c415a3618cba855bcc85b09795189e&callback=CASOmTvWnCuMJeETo&_=1572277191008"
  4. headers = {
  5. 'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
  6. 'referer': 'https://hotels.ctrip.com/hotel/469055.html?isFull=F&masterhotelid=469055&hcityid=2',
  7. 'accept': '*/*',
  8. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
  9. }
  10. formData = {
  11. 'hotel': str(hotel),
  12. 'currentPage': str(page),
  13. 'eleven': '12488c2f039b057861112f7bc2f1322271c415a3618cba855bcc85b09795189e',
  14. 'callback': 'CASOmTvWnCuMJeETo',
  15. '_': '1572277191008',
  16. }
  17. r = requests.post(url, headers=headers)
  18. r.raise_for_status()
  19. r.encoding = "utf-8"
  20. print(r.text)
  21. fetchCmts( '469055', 1)

运行代码,果然,可以获取到数据。

不过,这个可不能高兴的太早,为什么呢?

你看 Form Data 的参数中,有三个参数 eleven,callback 和 _ ,这三个的值有点奇怪,一长串看不懂的数字和字母,而且每次的值都不一样。

'_' 的值,1572277191008,这个有点熟悉,好像是时间戳,找在线工具解析一下,没错,果然是。

内心咯噔一下,坏了!

根据经验来讲,参数中带时间戳的,请求一般都是有时效性的。什么意思呢?就是这类请求的参数都是根据一定的规则动态生成的,而且一般几分钟之内就会失效。(再次运行上面的代码,果然啥也获取不到了,失效了)。

 也就是说,如果我想通过 Ajax 请求去获取数据的话,我必须搞清楚这三个参数的生成规则。

而这些参数又是经过 JS 加密的,搞这个又涉及到了 JS 逆向的东西。。。

我其实去网上查过携程网酒店爬虫,想看看别人是怎么绕过这个反爬机制的。

结果搜出来的好几个结果,都是用 Selenium webdriver 爬的。那个是什么原理呢。

就是我们正常的思路,是用爬虫直接去访问网站获取数据,爬虫伪装不好的话很容易被发现;

而它们这个,相当于是爬虫操作一个真的浏览器去访问网站,对方网站看到的是真正的浏览器在访问,它怎么也想不到操作浏览器的不是人,而是一只爬虫。所以这个方法几乎可以绕过所有的反爬机制。

不过!!!!

一个爬虫玩家的尊严,不允许我使用这种低效率又无脑的方式(误,手动狗头保命)。

于是我决定硬刚 Ajax 请求!!

 不过 JS 逆向哪有这么容易的,一时半会儿也搞不定(记得我第一次做 JS 逆向时,整整调试了一个礼拜的 JS 代码才搞出来),而那边小老弟要的又比较急......

正在我一筹莫展之际,看到了一张帖子,有个老哥的回答让我茅塞顿开。

对呀,网页端的不行,那就模拟手机端的来试试。 

网址由 https://hotels.ctrip.com/hotel 变成了 https://m.ctrip.com/webapp/hotel 。

手机版的评论不是点页码翻页的,是划到页面底部时候自动加载下一页内容的,然后我们在 开发者工具中 成功抓到了评论数据的请求包。

再看一下它的参数列表,嗯,还好,没有奇奇怪怪的动态加密的参数了。

 这次怎么样呢?写段代码验证一下吧。


  
  
  1. import requests
  2. def fetchCmts(hotel, page):
  3. url = "https://m.ctrip.com/restapi/soa2/16765/gethotelcomment?&_fxpcqlniredt=09031074110034723384"
  4. headers = {
  5. 'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
  6. 'Origin': 'https://m.ctrip.com',
  7. 'accept': '*/*',
  8. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
  9. }
  10. formData = {
  11. 'groupTypeBitMap': '2',
  12. 'hotelId': str(hotel),
  13. 'pageIndex': str(page),
  14. 'pageSize': '10',
  15. 'travelType': '-1', # -1 表示全部,家庭亲子为 30
  16. }
  17. r = requests.post(url, data=formData, headers=headers) # formData,
  18. r.raise_for_status()
  19. r.encoding = "utf-8"
  20. return r.text
  21. fetchCmts( '6410223', 1)

运行程序,可以获取到结果,修改酒店编号,修改页码,再运行都没问题。

返回的结果是 json格式的,回头用 json 库解析一下,把关键数据提取出来就可以了。 

 

事情进行到这儿,对目标网站的分析研究也就基本结束了。

酒店列表,评论数据的爬取,流程也基本跑通了,接下来只需要把代码整理一下,爬就完事儿了。

 

二、爬虫代码编写

前面将网站的爬取思路已经捋清楚了,而且做了些小测试也基本跑通了,接下来就是撸码环节了。

1. 获取酒店列表

我们其实也发现了,爬取评论数据时,只需要酒店ID和页码两个参数就够了,所以爬酒店列表时,我们只需要提取 酒店ID 即可。


  
  
  1. import requests
  2. import json
  3. def fetchHotel(city, star, page):
  4. url = "https://hotels.ctrip.com/Domestic/Tool/AjaxHotelList.aspx"
  5. headers = {
  6. 'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
  7. 'Origin': 'https://hotels.ctrip.com',
  8. 'Referer': 'https://hotels.ctrip.com/hotel/beijing1',
  9. 'accept': '*/*',
  10. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
  11. }
  12. formData = {
  13. 'cityId': city,
  14. 'star': star,
  15. 'page': page,
  16. }
  17. # 发起网络请求
  18. r = requests.post(url, data=formData,headers=headers)
  19. r.raise_for_status()
  20. r.encoding = r.apparent_encoding
  21. # 解析 json 文件,提取酒店数据
  22. json_data = json.loads(r.text)[ 'hotelPositionJSON']
  23. hotelList = []
  24. for item in json_data:
  25. hotelId = item[ 'id']
  26. hotelList.append(hotelId)
  27. return hotelList

2. 爬取评论数据


  
  
  1. import requests
  2. import json
  3. def fetchCmts(hotel, page):
  4. url = "https://m.ctrip.com/restapi/soa2/16765/gethotelcomment?&_fxpcqlniredt=09031074110034723384"
  5. headers = {
  6. 'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
  7. 'Referer': 'https://m.ctrip.com/webapp/hotel/hoteldetail/dianping/'+ hotel + '.html?&fr=detail&atime=20191027&days=1',
  8. 'Origin': 'https://m.ctrip.com',
  9. 'accept': '*/*',
  10. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
  11. }
  12. formData = {
  13. 'groupTypeBitMap': '3',
  14. 'auth': "",
  15. 'cid': "09031074110034723384",
  16. 'ctok': "",
  17. 'cver': "1.0",
  18. 'extension': '[]',
  19. 'lang': "01",
  20. 'sid': "8888",
  21. 'syscode': "09",
  22. 'hotelId': str(hotel),
  23. 'needStatisticInfo': '0',
  24. 'order': '0',
  25. 'pageIndex': str(page),
  26. 'pageSize': '10',
  27. 'tagId': '0',
  28. 'travelType': '-1',
  29. }
  30. r = requests.post(url, data=formData, headers=headers) # formData,
  31. r.raise_for_status()
  32. r.encoding = r.apparent_encoding
  33. json_data = json.loads(r.text)
  34. cmtsList = []
  35. hotelName = json_data[ 'hotelName']
  36. for item in json_data[ 'othersCommentList']:
  37. cmt = []
  38. userName = item[ 'userNickName']
  39. travelType = item[ 'travelType']
  40. baseRoomName = item[ 'baseRoomName']
  41. checkInDate = item[ 'checkInDate']
  42. postDate = item[ 'postDate']
  43. ratingPoint = item[ 'ratingPoint']
  44. content = item[ 'content']
  45. cmt.append(userName)
  46. cmt.append(hotelName)
  47. cmt.append(travelType)
  48. cmt.append(baseRoomName)
  49. cmt.append(checkInDate)
  50. cmt.append(postDate)
  51. cmt.append(ratingPoint)
  52. cmt.append(content)
  53. cmtsList.append(cmt)
  54. return cmtsList

3. 数据保存函数

将数据保存到 csv 文件中。


  
  
  1. import pandas as pd
  2. import os
  3. def saveCmts(path, filename, data):
  4. # 如果路径不存在,就创建路径
  5. if not os.path.exists(path):
  6. os.makedirs(path)
  7. # 保存文件
  8. dataframe = pd.DataFrame(data)
  9. dataframe.to_csv(path + filename, encoding= 'utf_8_sig', mode= 'a', index= False, sep= ',', header= False )

4. 爬虫调度器

由于小老弟提的要求是: 上海静安香格里拉大酒店,家庭亲子类型的,评论数据。所以,

在 fetchCmts 中,将 travelType 的值设置为 30,

'travelType': '30',   # 30 表示 家庭亲子 类型
  
  

由于看到评论区内容只有九百多条, 每页显示 10 条,所以我们将页码范围设置为 1 - 100 。


  
  
  1. import time
  2. if __name__ == '__main__':
  3. hotel = '469055' # 上海静安香格里拉大酒店
  4. startPage = 1
  5. endPage = 100
  6. path = 'Data/'
  7. filename = 'cmtTest.csv'
  8. for p in range(startPage, endPage+ 1):
  9. cmts = fetchCmts(hotel, p)
  10. saveCmts(path, filename, cmts)
  11. time.sleep( 0.5)

 为了保险期间,还加了一个 sleep 函数,每爬一次歇半秒,免得因为爬取太频繁被发现。

 几分钟之后,爬取完成,共爬取到 735 条数据。至此,小老弟的忙总算是帮完了。

 

不过,最开始也说了,我嫌爬的不过瘾,又给自己加了几条需求。

爬取北京市的,所有四星级以上酒店的,所有类型的评价数据。


  
  
  1. import time
  2. if __name__ == '__main__':
  3. city = '1'
  4. star = '4,5'
  5. startPage = 1
  6. hotelEndPage = 30
  7. cmtsEndPage = 100
  8. for page in range(startPage, hotelEndPage + 1):
  9. hotelList = fetchHotel(city, star, page)
  10. for hotel in hotelList:
  11. for p in range(startPage, cmtsEndPage + 1):
  12. cmts = fetchCmts(hotel, p)
  13. saveCmts( "Data/", "cmtTest.csv", cmts)
  14. time.sleep( 1)
  15. print( "爬取完成")

 这里偷了个懒,具体有多少酒店,每个酒店有多少评论我们不去管它了,就爬 30 页的酒店,每个酒店爬 100 页的评论,

大概就是爬 300 个酒店,每个酒店 1000 条左右的评论,差不多可以了,如果想爬更多的话,可以自行去修改页码范围。


后记

这个爬虫给了我一个新的启示,就是,遇到问题,我们要有死磕的觉悟,但是也要有灵活变通的思维。

就像这个爬虫,爬取评论信息时,PC 版网页的请求加了密不好整,那就换个途径,从手机端来获取数据。

时间也省了,事儿也办了,岂不快哉。

 


2019年12月18日 更新

有读者反馈说,在抓取酒店列表信息的部分,使用文章中的代码无法正常获取数据。

运行代码的结果是这样的,也不报错,就是返回的搜索结果是 0 条。

经调试发现,可能是对方服务器做了调整,需要验证 cookies 信息,只需要在 headers 中添加 cookies 参数即可。

 

2020年6月20日 更新

距离这个爬虫写好已经比较久了,期间对方网站也做过一些反爬机制的调整导致爬虫失效。

很多读者反馈说,前面更新时说的向 headers 中添加 cookies 的方法也失效了。经过测试,确实是,现在网站需要验证 “登陆账号后” 的 cookie 了,注意是登陆账号后的,未登录的cookie爬出来还是0条。

后续网站是否会有调整我不知道,截至本次更新时,添加登陆账号后的 cookie 后,文中的爬虫仍是有效的。(可能有些读者刚刚接触爬虫,不知道 cookie 加在哪儿,下面贴一段测试代码,大家参考)


  
  
  1. import requests
  2. def fetchCmts(hotel, page):
  3. url = "https://m.ctrip.com/restapi/soa2/16765/gethotelcomment?&_fxpcqlniredt=09031074110034723384"
  4. headers = {
  5. 'Content-type': 'application/x-www-form-urlencoded; charset=UTF-8',
  6. 'Origin': 'https://m.ctrip.com',
  7. 'accept': '*/*',
  8. 'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.120 Safari/537.36',
  9. 'cookie': '这里放登陆账号后登陆账号后登陆账号后的cookie',
  10. }
  11. formData = {
  12. 'groupTypeBitMap': '2',
  13. 'hotelId': str(hotel),
  14. 'pageIndex': str(page),
  15. 'pageSize': '10',
  16. 'travelType': '-1', # -1 表示全部,家庭亲子为 30
  17. }
  18. r = requests.post(url, data=formData, headers=headers) # formData,
  19. r.raise_for_status()
  20. r.encoding = "utf-8"
  21. print(r.text)
  22. return r.text
  23. fetchCmts( '10246623', 2)

对方网站反爬机制升级,也是侧面反映了网站收到各种爬虫爬取的困扰很大。

希望大家在爬取数据时,注意控制爬取节奏,时间允许的范围内,尽量放慢爬取速度。

 


 如果文章中有哪里没有讲明白,或者讲解有误的地方,欢迎在评论区批评指正,或者扫描下面的二维码,加我微信,大家一起学习交流,共同进步。

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python网络爬虫实战:爬取携程网酒店评价信息 的相关文章

  • 操作数无法与形状 (128,) (0,) 错误一起广播

    我正在尝试实现面部识别登录系统 但出现错误 操作数无法与形状 128 0 一起广播 我不知道什么或如何解决它 这是我已实现的 view py 和 FaceDetector py 以及我从服务器收到的错误 errors Traceback m
  • Python 遍历目录树的方法是什么?

    我觉得分配文件和文件夹并执行 item 部分有点黑客 有什么建议么 我正在使用Python 3 2 from os import from os path import def dir contents path contents list
  • Python + PostgreSQL + 奇怪的ascii = UTF8编码错误

    我有包含字符的 ascii 字符串 x80 代表欧元符号 gt gt gt print x80 当将包含该字符的字符串数据插入数据库时 我得到 psycopg2 DataError invalid byte sequence for enc
  • Python sqlite3游标没有属性commit

    当我运行这段代码时 path Scripts wallpapers single png conn sqlite3 connect Users Heaven Library Application Support Dock desktopp
  • 字典中的列表,Python 中的循环

    我有以下代码 TYPES hotmail type hotmail lookup mixed dkim no signatures S Return Path email protected cdn cgi l email protecti
  • 如何找到列表S的所有分区为k个子集(可以为空)?

    我有一个唯一元素列表 比方说 1 2 我想将其拆分为 k 2 个子列表 现在我想要所有可能的子列表 1 2 1 2 2 1 1 2 我想分成 1 1 2 我怎样才能用 Python 3 做到这一点 更新 我的目标是获取 N 个唯一数字列表的
  • Pyspark 数据框逐行空列列表

    我有一个 Spark 数据框 我想创建一个新列 其中包含每行中具有 null 的列名称 例如 原始数据框是 col 1 col 2 col 3 62 45 null 62 49 56 45 null null null null null
  • 使用 Scipy imsave 将 Numpy 数组保存到图像时保留未更改的数据

    使用 Scipy 保存二维 Numpy 数组 单个值 时toimage or imsave像素值与 Numpy 数组中的像素值不完全匹配 相反 在某些区域 主要是边缘 图像算法似乎使用某种插值 是否有一个选项可以停止插值并保留准确的数据 例
  • 网页抓取 - 前往第 2 页

    如何访问数据集的第二页 无论我做什么 它都只返回第 1 页 import bs4 from urllib request import urlopen as uReq from bs4 import BeautifulSoup as sou
  • 如何使用 Python 多处理避免在分叉进程中加载​​父模块

    当您创建一个Pool使用Python的进程multiprocessing 这些进程将分叉 父进程中的全局变量将显示在子进程中 如下面的问题所述 如何限制多处理进程的范围 https stackoverflow com questions 2
  • 如何从 Python 中指定运行程序的输入文件?

    我正在编写一个外部脚本 以通过笔记本电脑上的 Python mrjob 模块 而不是在 Amazon Elastic Compute Cloud 或任何大型集群上 运行 mapreduce 作业 我读自mrjob文档 http packag
  • Python 视频框架

    我正在寻找一个 Python 框架 它将使我能够播放视频并在该视频上绘图 用于标记目的 我尝试过 Pyglet 但这似乎效果不是特别好 在现有视频上绘图时 会出现闪烁 即使使用双缓冲和所有这些好东西 而且似乎没有办法在每帧回调期间获取视频中
  • Spark中的count和collect函数抛出IllegalArgumentException

    当我使用时抛出此异常时 我尝试在本地 Spark 上加载一个小数据集count 在 PySpark 中 take 似乎有效 我试图搜索这个问题 但没有找到原因 看来RDD的分区有问题 有任何想法吗 先感谢您 sc stop sc Spark
  • Django 接受 AM/PM 作为表单输入

    我试图弄清楚如何使用 DateTime 字段在 Django 中接受 am pm 作为时间格式 但我遇到了一些麻烦 我尝试在 forms py 文件中这样设置 pickup date time from DateTimeField inpu
  • 大型数据集上的 Sklearn-GMM

    我有一个很大的数据集 我无法将整个数据放入内存中 我想在这个数据集上拟合 GMM 我可以用吗GMM fit sklearn mixture GMM 重复小批量数据 没有理由重复贴合 只需随机采样您认为机器可以在合理时间内计算的尽可能多的数据
  • Spyder 如何在同一线程的后台运行 asyncio 事件循环(或者确实如此?)

    我已经研究 asyncio 模块 功能几天了 因为我想将它用于我的应用程序的 IO 绑定部分 并且我认为我现在对它的工作原理有一个合理的理解 或者在至少我认为我已经理解了以下内容 任一时刻 任一线程中只能运行一个异步事件循环 一旦一切都设置
  • 如何正确消除字典中的元素直到只剩下一个字符串

    我真的需要这方面的帮助 def get winner dict winner new dict for winner in dict winner first letter winner 0 value dict winner winner
  • SQLAlchemy:避免声明式样式类定义中的重复

    我正在使用 SQLAlchemy 并且我的对象模型中的许多类具有相同的两个属性 id 和 整数和主键 以及名称 字符串 我试图避免在每个类中声明它们 如下所示 class C1 declarative base id Column Inte
  • 获取调用者文件的绝对路径

    假设我在不同的目录中有两个文件 1 py 比如说 在C FIRST FOLDER 1 py and 2 py 比如说 在C SECOND FOLDER 2 py 文件1 py进口2 py using sys path insert 0 pa
  • issubclass() 对从不同路径导入的同一类返回 False

    目的是实现某种插件框架 其中插件是同一基类 即 A 的子类 即 B 基类使用标准导入加载 而子类使用 imp load module 从众所周知的包 即 pkg 的路径加载 pkg init py mod1 py class A mod2

随机推荐

  • opencv-python实现去雾操作

    通过仿真自动色阶算法 发现其去雾效果十分明显 并且速度快于暗通道算法 python实现 python3 6 import numpy as np import cv2 def ComputeHist img h w img shape hi
  • LINUX下编译c++11的代码

    C 11 即ISO IEC 14882 2011 是目前的C 编程语言的最新正式标准 它取代了第二版标准 第一版公开于1998年 第二版于2003年更新 分别通称C 98以及C 03 两者差异很小 新的标准包含核心语言的新机能 而且扩展C
  • Ubuntu 18 系统中对openssl进安降级安装方法总结

    1 下载openssl 下载链接 https www openssl org source snapshot 里边是当前仍支持版本的快照 同版本不同日期内容可能不同的 所以下载一般下对应版本的最新快照 安装出错则尝试另一个快照 解压后的文件
  • qt中的菜单栏的隐藏功能

    有时候为了能让菜单栏中的部分功能进行隐藏 我们就需要在构造函数中进行操作 一般的控件隐藏可以直接hide 就行 然后菜单栏中的部分功能进行隐藏 就需要ui gt 菜单栏名称 gt menuAction gt setVisible false
  • 5G NR 网络切片是什么意思

    网络切片可以理解为支持特定使用场景或商业模式的通信服务要求的一组逻辑网络功能的集合 是基于物理基础设施对服务的实现 这些逻辑网络功能可以看作是由EPC下的网络功能 NetworkFuncTIon 分解而来的一系列子功能 Networksub
  • 线性代数—学习笔记

    对分类超平面方程
  • ubutun安装停留在界面

    这几天都在折腾 都在出问题记录一下 ubuntu安装时停留在界面 怎么办解决方法 重新开机 光标选中 Install Ubuntu 按 e 进入grub界面 将倒数第二行中的 quiet splash 改为 nomodeset F10保存
  • 比例谐振(PR)控制器的学习过程记录

    目录 0 前言 1 PR控制器和PI控制器对比 1 1 传递函数表达式对比 1 2 波特图对比 2 离散化预备知识 2 1 离散化表达式 2 2 离散化方法 2 3 离散化练习题 3 使用Matlab离散PR控制器 4 逆变器仿真模型中使用
  • STM32传感器外设集--语音识别模块(LD3320)

    目录 本节主要贴上以前写的语音识别外设LD3320 希望对大家有用 本人已经测试过有用 如何使用 将下面这段函数添加到功能函数中 LD3320 h LD3320 c 本节主要贴上以前写的语音识别外设LD3320 希望对大家有用 本人已经测试
  • 机器学习之 决策树(Decision Tree)

    机器学习算法系列 机器学习 之线性回归 机器学习 之逻辑回归及python实现 机器学习项目实战 交易数据异常检测 机器学习之 决策树 Decision Tree 机器学习之 决策树 Decision Tree python实现 机器学习之
  • 保险业的变革,软件机器人车险录入自动化

    在现代社会 技术的迅猛发展正在改变各行各业的运作方式 包括保险业 随着数字化转型的推进 保险公司采用创新技术来提高效率和准确性 博为小帮软件机器人结合自动化的功能和OCR技术的识别能力 实现了车险单处理流程的全自动化 本文将深入探讨这一技术
  • 漏洞扫描工具 -- awvs13

    我羡慕那些又帅又有钱的男生 他们拥有过很多女孩的青春 而我 只能拼命赚钱 才能拥有一个爱过别人的姑娘 awvs是一款知名的Web网络漏洞扫描工具 它通过网络爬虫测试你的网站安全 检测流行安全漏洞 一 安装主程序 一路下一步 二 绿化程序 1
  • 9、cglib demo分析以及methodProxy与Fastclass源码

    前言 上一节讲了say方法最终会转发 在demo中 cglib CglibProxy intercept这个里面用了 Object result methodProxy invokeSuper o objects 这个invokeSuper
  • Django 出现:Could not parse the remainder: 'date::'Y /m /d''

    在项目中练习中使用动态Url的时候在日期format的时候出现 Could not parse the remainder date Y m d from post date time date Y m d 这里主要是自己跟着练习的时候出现
  • Lodop、C-Lodop页面找不到报404错误解决

    在使用 Lodop C Lodop打印控件时 使用火狐浏览器不报错 换成IE浏览器时报404错误 找不到控件的下载位置 以前的配置如下 1 spring servlet xml中配置 找到打印控件的位置
  • 微信小程序开发1.简易教程

    微信小程序 简易教程 一 基础 第一章 起步 开发小程序的第一步 你需要拥有一个小程序帐号 通过这个帐号你就可以管理你的小程序 跟随这个教程 开始你的小程序之旅吧 申请账号 点击 https mp weixin qq com wxopen
  • C++ 面向对象之引用

    前言 引用是c 区别于c的一个特别好用的特性 它和指针的作用很相似 或者说类似于指针中的常量指针 本文将会从其语法 注意事项 做函数等方面浅谈引用 同时 本文参考了B站视频 链接如下 https www bilibili com video
  • 小白的福音—秒懂UDP协议&TCP协议

    ForeWord 本文介绍了UDP TCP协议的基础知识 主要内容有 UDP TCP协议在TCP IP协议栈中的位置和作用 UDP TCP协议数据段格式 TCP协议如何保证数据传输的可靠性 tips 全文阅读需5min 小伙伴们燥起来 TC
  • 在Linux中配置Samba服务器实现网盘

    在Linux中配置Samba服务器实现网盘 文章目录 在Linux中配置Samba服务器实现网盘 1 安装与基本配置 2 在Windows中使用共享文件夹 3 高级配置 3 1 smb cfg 文件详解 3 2 多用户 多用户组 3 3 典
  • Python网络爬虫实战:爬取携程网酒店评价信息

    这个爬虫是在一个小老弟的委托之下写的 他需要爬取携程网上的酒店的评价数据 来做一些分词和统计方面的分析 然后来找我帮忙 爬这个网站的时候也遇到了一些有意思的小麻烦 正好整理一下拿出来跟大家分享一下 这次爬取过程稍微曲折 各种碰壁 最终成功的