我在一个实验中,需要获得key为list对应的值,值是lxml文本,最后交给beautifulSoup解析,所以对文本格式要求严格。
从网页请求中的数据往往是json格式数据。我们通过爬虫获取时,一般不能直接得到原始的json,而是首先得到byte或str再转成dic或json【这里我们不严格比较dic和json的差异了】,进而获得值。
这里记录下我的清洗方法。我们直接读取的结果是【省略了很多】:
b'{"list":" \\n <div class=\\"row row-line \\">\\n <div class=\\"wrapper\\">\\n <div class=\\"line-panel clearfix\\">\\n <dl class=\\"lp-detail\\">\\n <dt>\\n <div class=\\"days-season\\">\\n <span class=\\"item\\">\\n <i class=\\"icon-days\\"><\\/i>\\n \\u6e38\\u73a9\\u65f6\\u95f4\\uff1a<strong>6\\u5929<\\/strong>\\n <\\/span>\\n <span class=\\"divide\\"><\\/span>\\n <span class=\\"item\\">\\n <i class=\\"icon-season\\"><\\/i>\\n \\u6700\\u4f73\\u5b63\\u8282\\uff1a<strong>\\u5168\\u5e74<\\/strong>\\n <\\/span>\\n <\\/div>\\n <a href=\\"\\/mdd\\/cityroute\\/10065_5934.html\\" target=\\"_blank\\">\\n <h2>\\u5317\\u4eac6\\u65e5\\u7ecf\\u5178\\u7ebf\\u8def<\\/h2>\\n <p><em>35%<\\/em>\\u8702\\u8702\\u4f1a\\u9009\\u62e9\\u8fd9\\u6761\\u7ebf\\u8def<\\/p> <\\/a>\\n <\\/dt>\\n <dd>\\n <p>D1\\n <a class=\\"cityroutetext\\" href=\\"\\/mdd\\/cityroute\\/10065_5934.html\\" target=\\"_blank\\">\\n <span>\\u5929\\u5b89\\u95e8\\u5e7f\\u573a<\\/span>\\n <\\/a>\\n <a class=\\"cityroutetext\\" href=\\"\\/mdd\\/cityroute\\/10065_5934.html\\" target=\\"_blank\\">\\n <span class=\\"arrow\\">\\u2192<\\/span><span>\\u524d\\u95e8\\u5927\\u8857<\\/span>\\n <\\/a>\\n <a class=\\"cityroutetext\\" href=\\"\\/mdd\\/cityroute\\/10065_5934.html\\" target=\\"_blank\\">\\n <span class=\\"arrow\\">\\u2192<\\/span><span>\\u5317\\u4eac\\u5168\\u805a\\u5fb7(\\u524d\\u95e8\\u5e97)<\\/span>\\n <\\/a>\\n <a class=\\"cityroutetext\\" href=\\"\\/mdd\\/cityroute\\/10065_5934.html\\" target=\\"_blank\\">\\n <span class=\\"arrow\\">\\u2192<\\/span><span>\\u6545\\u5bab<\\/span>\\n <\\/a>\\n <a class=\\"cityroutetext\\" href=\\"\\/mdd\\/cityroute\\/10065_5934.html\\" target=\\"_blank\\">\\n <span class=\\"arrow\\">\\u2192<\\/span><span>\\u666f\\u5c71\\u516c\\u56ed<\\/span>\\n <\\/a>\\n <\\/p>\\n <p>D2\\n <a class=\\"cityroutetext\\" href=\\"\\/mdd\\/cityroute\\/10065_5934.html\\" target=\\"_blank\\">\\n <span>\\u5929\\u575b<\\/span>\\n <\\/a>
...
"}'
依据我的需求,直接读取的文本有以下问题:
- 得到的字符串文本是byte类型,而原始的是json
- lxml标签文本输出为Unicode编码,无法显示人类能理解的文字
- 闭合标签(右标签)的 斜杠 / ,左边留下了多余的//
- 换行转义字符\n由于多了一个\变成了\\,导致直接输出了\\n
于是,我们需要做以下四件事:
-
把byte转换为str(byte不能直接转dic,必须通过str过渡)
-
把str转换为dic
-
获取dic中,键list对应的值
-
继续处理值中的斜杠
Step1:把byte转换为str
r = requests.post(url,headers=headers,data=post_data)
# apparent_encoding是机器识别出的编码类型,encoding是请求获得的编码类型。前者更加精确
r.encoding=r.apparent_encoding
#byte转str
str_r_con=bytes.decode(r.content,encoding=r.encoding)
Step2:把str转换为dic
# str转dic
dic_r_con = eval(str_r_con)
Step3:获取dic中,键list对应的值
value=dic_r_con['list']
至此,我们输出value的值看看,以下是一部分。
<div class="row row-line ">
<div class="wrapper">
<div class="line-panel clearfix">
<dl class="lp-detail">
<dt>
<div class="days-season">
<span class="item">
<i class="icon-days"><\/i>
游玩时间:<strong>6天<\/strong>
<\/span>
<span class="divide"><\/span>
<span class="item">
<i class="icon-season"><\/i>
最佳季节:<strong>全年<\/strong>
<\/span>
<\/div>
<a href="\/mdd\/cityroute\/10065_5934.html" target="_blank">
<h2>北京6日经典线路<\/h2>
<p><em>35%<\/em>蜂蜂会选择这条线路<\/p> <\/a>
<\/dt>
<dd>
<p>D1
<a class="cityroutetext" href="\/mdd\/cityroute\/10065_5934.html" target="_blank">
<span>天安门广场<\/span>
<\/a>
<a class="cityroutetext" href="\/mdd\/cityroute\/10065_5934.html" target="_blank">
<span class="arrow">→<\/span><span>前门大街<\/span>
我们发现还存在一个问题,所有的 单斜杠 / 都变成了双斜杠 //,这是我们不允许的。所以有了第四步,很简单,替换就好。
Step4:继续处理值中的斜杠
res=value.replace('\/','/')
结果:
<div class="row row-line ">
<div class="wrapper">
<div class="line-panel clearfix">
<dl class="lp-detail">
<dt>
<div class="days-season">
<span class="item">
<i class="icon-days"></i>
游玩时间:<strong>6天</strong>
</span>
<span class="divide"></span>
<span class="item">
<i class="icon-season"></i>
最佳季节:<strong>全年</strong>
</span>
</div>
<a href="/mdd/cityroute/10065_5934.html" target="_blank">
<h2>北京6日经典线路</h2>
<p><em>35%</em>蜂蜂会选择这条线路</p> </a>
</dt>
<dd>
<p>D1
<a class="cityroutetext" href="/mdd/cityroute/10065_5934.html" target="_blank">
<span>天安门广场</span>
</a>
<a class="cityroutetext" href="/mdd/cityroute/10065_5934.html" target="_blank">
<span class="arrow">→</span><span>前门大街</span>
emm, 现在可以放心的传给BeautifulSoup了。
总结以下,看起来都是简单的步骤,但是尤其注意细节问题,因为交给BeautifulSoup处理时,任何一个小问题都会导致报错,一般是报堆栈溢出错误。