暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

手把手教你从今日头条爬取你想要的任何图片

shysheng 2019-05-31
1321

都说人生苦短,我用python。为了找点乐趣,不如写个爬虫?

那爬什么呢?

宇宙条是爬虫界行家,它的很多信息都是从其它网站爬来的,那就拿它练练手吧。

网上类似的文章其实不少,但是大多是很久之前的,在这期间头条已经做了改版,因此还必须自己动手。

具体原理不多说了,直接简单介绍下步骤:

1.首先,打开头条首页,搜索关键词「美景」,可以得到搜索结果页面链接为https://www.toutiao.com/search/?keyword=美景,搜索结果如下:

2.同时注意到这是一个Ajax请求,因此我们需要拿到其真实的请求url,就是图中红框标出来的部分。

3.第一次发起搜索请求时,头条有一个滑块验证,这里我们就不模拟这个过程了,手动验证,拿到cookie就好,同时将自己的浏览器信息,请求参数都复制出来:

连续向后翻页,发现变化的参数只有offset一个,也就是偏移量。

4.观察请求结果,最关键的是article_url这个字段,根据这个链接重定向,就可以跳转到列表中每篇文章的详情页。

5.进入详情页,查看网页源码,可以发现图片链接都是以下图标出来的形式记录的,这就好办了,简单正则匹配一下就好

6.拿到图片链接,保存到本地,大功告成。

应该说头条相对来说做得比较简单一些,毕竟是新闻类网站,总共差不多100行代码就搞定了,不像淘宝,要爬它的数据就要困难很多。

当然了,除了爬美景,其它照片你想爬啥就怕啥,修改下搜索关键字就好了。第一次写爬虫,还有很多可以优化的地方。简单贴下代码,需要的自取,鬼晓得头条啥时候又改版了,同时欢迎大家review😝。

最后,祝各位大小宝宝节日快乐~~~~

  1. # -*- coding: utf-8 -*-

  2. import os

  3. import re

  4. import threading

  5. import time

  6. from hashlib import md5

  7. from urllib import urlencode


  8. import requests


  9. # 这里设置你想查询的关键字

  10. keyword = '美景'

  11. # 这里替换成你自己的浏览器信息

  12. user_agent = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36'

  13. # 头条图片搜索需要滑动验证,因此简单处理,先手动验证,然后设置cookie

  14. cookie = 'tt_webid=6696746174420534791; WEATHER_CITY=%E5%8C%97%E4%BA%AC; UM_distinctid=16b0805ea6f31d-02830a8210d05a-37627e03-1fa400-16b0805ea705fd; tt_webid=6696746174420534791; __tasessionId=znvodagrm1559207733945; csrftoken=7201998104473d4e2ad8302bb74ae401; s_v_web_id=600eabfd649cb7a70f3d80b981411bfc; CNZZDATA1259612802=1444442826-1559202415-%7C1559207815'

  15. headers = {

  16. 'Host': 'www.toutiao.com',

  17. 'Referer': 'https://www.toutiao.com/search/?keyword=' + keyword,

  18. 'User-Agent': user_agent,

  19. 'X-Requested-With': 'XMLHttpRequest',

  20. 'Cookie': cookie

  21. }


  22. start_offset = 0

  23. end_offset = 20

  24. step = 20



  25. # 根据偏移量获取每页文章列表

  26. def get_page_by_offset(offset):

  27. params = {

  28. 'aid': '24',

  29. 'app_name': 'web_search',

  30. 'offset': offset,

  31. 'format': 'json',

  32. 'keyword': keyword,

  33. 'autoload': 'true',

  34. 'count': '20',

  35. 'en_qc': '1',

  36. 'cur_tab': '1',

  37. 'from': 'search_tab',

  38. 'pd': 'synthesis',

  39. }


  40. url = 'https://www.toutiao.com/api/search/content/?' + urlencode(params)

  41. try:

  42. resp = requests.get(url, headers=headers)

  43. if resp.status_code == 200:

  44. return resp.json()

  45. except requests.ConnectionError:

  46. return None



  47. # 获取每篇文章的重定向链接

  48. def get_article_url(article):

  49. if article.get('data'):

  50. for item in article.get('data'):

  51. article_url = item.get('article_url')

  52. title = item.get('title')

  53. yield {

  54. 'article_url': article_url,

  55. 'title': title

  56. }



  57. # 将图片保存到文件

  58. def save2file(title, url):

  59. if not os.path.exists(title):

  60. os.mkdir(title)

  61. resp = requests.get(url)

  62. file_name = './' + title + '/' + md5(resp.content).hexdigest() + '.jpg'

  63. if not os.path.exists(file_name):

  64. with open(file_name, 'wb') as f:

  65. f.write(resp.content)

  66. else:

  67. print('Already Downloaded', file_name)



  68. # 获取每篇文章的图片列表

  69. def get_image_by_article(article):

  70. article_url = article.get('article_url')

  71. title = article.get('title')

  72. print title

  73. print article_url

  74. if article_url:

  75. try:

  76. # 这里需要使用session的方式,否则会因为重定向次数太多而报错

  77. session = requests.Session()

  78. session.headers['User-Agent'] = headers['User-Agent']

  79. resp = session.get(article_url)

  80. if resp.status_code == 200:

  81. # soup = BeautifulSoup(resp.text, 'lxml')

  82. # result = soup.find_all(name='script')[6]

  83. regex = '.*?img src="(.*?)".*?'

  84. items = re.findall(regex, resp.text, re.S)

  85. if items:

  86. for item in items:

  87. print item

  88. save2file(title, item)

  89. except requests.ConnectionError:

  90. print 'Get image fail.'



  91. if __name__ == '__main__':

  92. for offset in range(start_offset, end_offset, step):

  93. article_list = get_page_by_offset(offset)

  94. for article in get_article_url(article_list):

  95. # 每篇文章单独起一个线程进行抓取

  96. t = threading.Thread(target=get_image_by_article(article))

  97. t.start()

  98. t.join()

  99. # get_image_by_article(article)

  100. end_time = time.time()

  101. print('=====Done=====')

文章转载自shysheng,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论