网页爬虫抓取百度图片(分析网页看看能不能获得网页源码打开今日头条官网(组图) )
优采云 发布时间: 2021-11-16 09:02网页爬虫抓取百度图片(分析网页看看能不能获得网页源码打开今日头条官网(组图)
)
分析网页
看看能不能拿到网页的源代码
打开今日头条官网,搜索“街拍美女”,跳转到街拍首页。在jupyter notebook中尝试get源码,你会发现没有你想要的图片信息。这种情况打消了我们直接分析首页源码,寻找详情页的想法。这时候就用ajax解析了。
点击首页进入其中一个街拍群图详情页,然后尝试获取源码,但是可以直接获取源码。这里可以直接使用正则表达式。
了解页面结构
在“街头美女”首页,打开勾选-网络-选择保存日志,XHR,然后刷新页面,下面会有很多请求,我们直接进入主题,选择其中一个请求,然后看看右边的预览。
展开数据,
我们发现data里面的数据好像和首页的栏目是一一对应的。
当然,这可能并不明显。我们展开数据,看看子节点的title:(中间忽略公众号,我们只需要“open url”中的信息,其他需要过滤。)
查看其他数据子节点,也可以在首页找到对应的栏目,ok,我们已经确定了战略目标:
从首页开始,请求json格式的网页数据,然后使用ajax解析请求,获取并分析首页的源码;
从源代码中提取有用的 URL;
然后通过URL获取详情页的图片。
关于循环爬行
还要看左边。当我们继续下拉主页时,就会有源源不断的新请求。其中,偏移量有明显变化。和前面的实战一样,我们可以通过改变属性的值来达到循环阅读的目的。
分析详情页面
这里有个小技巧:在详情页的图片上右键,选择“在新标签页中打开图片”,然后看新标签页的名字,这个名字(一般只有几个尾数),在doc Ctrl+F 搜索,ok,然后你会发现它们隐藏在哪个变量中(多搜索几张图确认)。此变量收录从中下载图片的图片的 URL。
注:遗憾的是,目前今日头条采取了反拍措施,大部分详情页无法获取源码,因此获取的图片数量非常有限。
附上完整的爬虫代码,“streetPhotos_Spider.py”:
import json
import os
from hashlib import md5
import pymongo
from multiprocessing.pool import Pool
from urllib.parse import urlencode
from requests.exceptions import RequestException
import re
import requests
from webspider.TouTiao.mgconfig import *
from json.decoder import JSONDecodeError
client = pymongo.MongoClient(MONGO_URL)
db = client[MONGO_DB]
def get_one_index(offset, keyword): # 获取主页源码,由于主页url是动态的,我们设置参数,以便以后的循环
data = { # 设置url后缀
'offset': offset,
'format': 'json',
'keyword': keyword,
'autoload': 'true',
'count': '20',
'cur_tab': 1,
}
url = 'https://www.toutiao.com/search_content/?' + urlencode(data) # 用'urlencode方法会将字典解析成字符串
try:
response = requests.get(url)
if response.status_code == 200:
return response.text
except RequestException:
print("请求主页失败!")
return None
def parse_page_index(html): # 解析主页源码
try: # 这个函数有可能传入的参数是None,此时应该捕获异常
data = json.loads(html) # 由于拿到的源码是json格式的,需要用json包来解析
if data and 'data' in data.keys(): # 如果有节点data,那么从该节点中寻找article_url
for item in data.get('data'):
yield item.get('article_url')
except JSONDecodeError:
pass
def get_page_detail(url): # 获取详情页源码,这里传入的参数将会是从主页中解析出的各个url
try:
response = requests.get(url)
if response.status_code == 200:
return response.text
except RequestException:
return None
def parse_page_detail(html): # 解析详情源码
images_pattern = re.compile('[a-zA-z]+://[^\s]*jpg', re.S) # 由于各个详情页结构大不相同,暂时截获所有URL
results = re.findall(images_pattern, html)
if results:
for result in results:
if len(result) > 55:
for result in results: download_images(result)
return {'url': result}
def save_to_mongo(result): # 将解析的结果保存到数据库
if db[MONGO_DB_TABLE].insert(result):
print('存储到MongoDB库', result)
return True
return False
def download_images(url): # 下载图片
print('当前正在下载:', url) # 显示调试信息
try:
response = requests.get(url)
if response.status_code == 200:
save_image(response.content) # 返回图片二进制信息
except RequestException:
print("请求图片出错", url)
return None
def save_image(content): # 保存图片到本地
file_path = '{0}/{1}.{2}'.format('D:\Workspace\PycharmProj\webspider\TouTiao\photo', md5(content).hexdigest(),
'jpg') # 为文件命名
if not os.path.exists(file_path):
with open(file_path, 'wb') as f:
f.write(content)
f.close()
def main(offset):
html = get_one_index(offset, KEYWORD) # 获取主页
for url in parse_page_index(html): # 从主页中解析出的各个详情页url
detail_html = get_page_detail(url)
if detail_html: # 若详情页存在,那么解析它
detail_result = parse_page_detail(detail_html)
if detail_result is not None: # 如果详情页非空,
if detail_result: save_to_mongo(detail_result) # 如果详情页有返回的url,那么保存进数据库
if __name__ == '__main__':
groups = [x * 20 for x in range(GROUP_START, GROUP_END + 1)]
pool = Pool() # 创建线程池
pool.map(main, groups) # 将main方法放到线程池中,会自动分割成多线程同时抓取
配置文件“mgconfig.py”放置在同一目录中。
MONGO_URL = 'localhost'
MONGO_DB = 'Toutiao'
MONGO_DB_TABLE = 'Toutiao'
GROUP_START = 1
GROUP_END = 30
KEYWORD = '街拍美女'
文件包结构: