Shell爬取知乎某问题下所有图片

    xiaoxiao2021-09-03  312

    1. 分析网络请求

    在Bash下使用curl分析网页源码,以这个问题 'https://www.zhihu.com/question/40753170' 为例–user-agent “Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36” ‘https://www.zhihu.com/question/40753170’

    (上一步得到的代码) | egrep -o 'data-original="1' | egrep -o 'https://2' | sort | uniq通过返回的内容可以看到只包含了前三个问题的url

    使用chrome的debug分析网络请求发现除上面的内容外,其余的内容都是通过一个API接口实现的,并且图片是懒加载的,但是只要能获取图片的地址就能下载

    而我们用到的变量仅有下面这两个questions/${question_num}/answers,offset=23当每次点击加载,都会获取20个回答

    用curl测试,发现返回了错误,并不是debug中预想的那样{"error": {"message": "u8bf7u6c42u5934u6216u53c2u6570u5c01u88c5u9519u8bef", "code": 100, "name": "AuthenticationInvalidRequest"}}

    继续分析,在request header中又发现了这样的字段 authorization: oauth 添加上 curl –user-agent ‘XXX’ -H ‘authorization: oauth c3cef7c66a1843f8b3a9e6a1e3160e20 ‘ ‘api_url’这次返回了正常的JSON格式的数据,思路就很清晰了

    2. 编写代码

    思路是这样通过修改offset,来获取所有的回答,并提取出HTML代码中的图片地址,用wget进行下载要注意的问题:如果不控制线程,服务器配置又不高,很容易资源耗尽,弄挂服务器 #!/bin/bash # download.sh # 爬取知乎某问题下的所有图片 # 使用 ./download.SH https://www.zhihu.com/question/XXXXXX if [ ! $1 ] then echo 'need question url' exit 1 fi # 获取问题num ques_num=`echo $1 | egrep -o '[0-9]+'` function gethtml() { curl --user-agent 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/59.0.3071.115 Safari/537.36' -H 'authorization: oauth c3cef7c66a1843f8b3a9e6a1e3160e20' $1 } gethtml $1 | egrep -o 'data-original="[^"]*' | egrep -o 'https://[^ ]*'| sort |uniq >> $$ .log api="https://www.zhihu.com/api/v4/questions/${ques_num}/answers?sort_by=default&include=data[*].is_normal,is_collapsed,annotation_action,annotation_detail,collapse_reason,is_sticky,collapsed_by,suggest_edit,comment_count,can_comment,content,editable_content,voteup_count,reshipment_settings,comment_permission,mark_infos,created_time,updated_time,review_info,relationship.is_authorized,is_author,voting,is_thanked,is_nothelp,upvoted_followees;data[*].author.follower_count,badge[?(type=best_answerer)].topics&limit=20&offset=" # 根据offset获取图片链接到 $$ .log offset=3 total=`gethtml $api$offset | egrep -o '"totals": [0-9][^,]*' | egrep -o '[0-9]+'` total=`expr $total + 20` api_html='' for((offset=3;offset<$total;offset+=20)) do api_html=`echo $api${offset}` gethtml $api_html| egrep -o 'data-original=\\"[^\]*' | egrep -o 'https://[^ ]*'|sort|uniq>> $$ .log & done wait echo 'get img url complete' max_th=50 #指定最大线程数,防止过多进程过分消耗资源 # 线程控制 function getimg() { if [[ $max_th -ge $((`ps | grep download.sh | wc -l` - 1)) ]] # 减一是前去‘grep fileme'的行 then { wget $url }& else getimg fi } # 下载图片 for url in `cat $$ .log` do getimg done wait echo 'downlad complete'

    3. 展示图片

    将下载下来的图片,写个脚本放进网页中,然后愉快的...(当然之前的html代码是要自己写的,要用lazy加载哦,因为图片太多...)

    #!/bin/bash #将图片链接写到网页中去 for name in `ls | egrep -o '[a-z0-9]+\.(jp|jpe|pn)g'` do echo '<li><img originalsrc="'${name}'" /></li>' done echo ' </ul> </div> </body> </html> '
    " ↩ ↩

    最新回复(0)