Python爬取今日头条搜索的照片。使用requests+正则表达式
来源:互联网 发布:园林设计手机教学软件 编辑:程序博客网 时间:2024/04/30 12:59
爬取网页:http://www.toutiao.com/search/?keyword=%E8%A1%97%E6%8B%8D
1,分析爬取页面,找到页面信息
在Chrome按F12打开开发者工具,查找网页内容的请求位置
找了doc中发现内容都是加载,查看JS内容页面内容无关。
在XHR中发现到我们想要的内容,页面内容是通过ajax加载进来的
查看Headers,可以得到Request URL和Query String,构造成完整的请求URL
编写请求索引页代码:
def get_index(offset, keyword): # 网页下拉后,页面重新加载新的内容,offset也增加20,因此offset和翻页有关 # keyword刚好是我们要搜索的内容-街拍 dict = { 'offset': offset, 'format': 'json', 'keyword': keyword, 'autoload': 'true', 'count': '20', 'cur_tab': '1' } # urlencode()把字典变成字符ASCII字符串 # 构造索引页url url = 'http://www.toutiao.com/search_content/?' + urlencode(dict) print('索引页url' + url) try: res = requests.get(url) if res.status_code == 200: return res.text return None except RequestException: print('索引页请求失败') return None
2,分析索引页代码,得到详情页内容
在开发者工具里面查看到代码,发现是比较整齐的js代码,用json.loads载入代码,再经过处理就可以得到想要的信息
代码:
def parse_index(html): # 请求的链接返回的json文件,用json.loads载入变成字典,解析出每个详情页的url try: js = json.loads(html) if js and 'data' in js.keys(): for item in js.get('data'): if item.get('article_url'): # 用生成器返回url yield item.get('article_url') except JSONDecodeError: pass
3.请求详情页
请求详情页和索引页类似,复制粘贴详情页请求,加上if 内容==None判断跳过URL出错的异常
def get_detail(url): print('下载:' + url) if url != None: try: res = requests.get(url) if res.status_code == 200: return res.text return None except RequestException: print('详情页请求失败') return None
4.得到详情页信息
详情页的图片信息在Doc也就是正常html文件中,但是是通过需要通过js加载后进行解析
标题信息比较简单,用BeautifulSoup.select就可以查找到。
通过对比发现,网页有2种不同的页面,一种静态的下拉页面,一种是左右播放页面,两个页面title标题信息的获取是一致的,但是图片信息不同。
下拉式:
图片url代码在content后面,使用正则表达式解析可以得到
播放页面:
图片url代码在 gallery:里面,使用正则表达式匹配,然后分解后可以去掉一些文字,转换成js字典格式,就可以到url了
最后以字典的形式返回爬取的信息
def parse_detail(html, url): if html == None: return None # 通过BeautifulSoup来查找title soup = BeautifulSoup(html, 'lxml') title = soup.select('title') title = title[0].text if title else'' # 因为有两个不一样的页面,所以有2个不一样的正则分析式 images_pattern1 = re.compile('img src="(.*?);', re.S) images_pattern2 = re.compile('gallery: {(.*?)},.*?siblingLis', re.S) res = re.findall(images_pattern1, html) # 第一种页面,如果能匹配到内容就存储起来 if res != []: results = [result.rstrip('"') for result in res] for ima in results: download_image(ima) return{ 'title': title, 'url': url, 'images': results } # 第二种页面,使用第二个正则表达式进行匹配,并储存结果 else: res = re.search(images_pattern2, html) if res: data = json.loads(res.group(0).lstrip('gallery: ').rstrip('siblingLis').strip().rstrip(',')) if data and 'sub_images' in data.keys(): sub_images = data.get('sub_images') images = [item.get('url') for item in sub_images] for image in images: download_image(image) return{ 'title': title, 'url': url, 'images': images }
5,下载,存储图片
def download_image(url): print('下载:'+url) try: res = requests.get(url) if res.status_code == 200: # 直接调用保持图片,传入参数网页的二进制信息 save_iamge(res.content) # res.contenst是二进制信息,因为下载图片需要二进制。 return None except RequestException: print('详情页请求失败') return Nonedef save_iamge(content): # 构造保持路径, {0}为当前目录路径,{1}为md5生成值,避免重复下载,{2}为文件格式 file_path = '{0}/images/{1}.{2}'.format(os.getcwd(), md5(content).hexdigest(), 'jpg') print(file_path) if not os.path.exists(file_path): # 如果 路径文件不存在 就下载 with open(file_path, 'wb') as f: f.write(content) # 传入二进制信息 f.close()
6,整合代码添加循环,爬取多页信息
import jsonfrom json import JSONDecodeErrorfrom urllib.parse import urlencodefrom hashlib import md5import reimport osfrom requests.exceptions import RequestExceptionimport requestsfrom bs4 import BeautifulSoupdef get_index(offset, keyword): # 网页下拉后,页面重新加载新的内容,offset也增加20,因此offset和翻页有关 # keyword刚好是我们要搜索的内容-街拍 dict = { 'offset': offset, 'format': 'json', 'keyword': keyword, 'autoload': 'true', 'count': '20', 'cur_tab': '1' } # urlencode()把字典变成字符ASCII字符串 # 构造索引页url url = 'http://www.toutiao.com/search_content/?' + urlencode(dict) print('索引页url' + url) try: res = requests.get(url) if res.status_code == 200: return res.text return None except RequestException: print('索引页请求失败') return Nonedef parse_index(html): # 请求的链接返回的json文件,用json.loads载入变成字典,解析出每个详情页的url try: js = json.loads(html) if js and 'data' in js.keys(): for item in js.get('data'): if item.get('article_url'): yield item.get('article_url') except JSONDecodeError: passdef get_detail(url): print('下载:' + url) if url != None: try: res = requests.get(url) if res.status_code == 200: return res.text return None except RequestException: print('详情页请求失败') return Nonedef parse_detail(html, url): if html == None: return None # 通过BeautifulSoup来查找title soup = BeautifulSoup(html, 'lxml') title = soup.select('title') title = title[0].text if title else'' # 因为有两个不一样的页面,所以有2个不一样的正则分析式 images_pattern1 = re.compile('img src="(.*?);', re.S) images_pattern2 = re.compile('gallery: {(.*?)},.*?siblingLis', re.S) res = re.findall(images_pattern1, html) # 第一种页面,如果能匹配到内容就存储起来 if res != []: results = [result.rstrip('"') for result in res] for ima in results: download_image(ima) return{ 'title': title, 'url': url, 'images': results } # 第二种页面,使用第二个正则表达式进行匹配,并储存结果 else: res = re.search(images_pattern2, html) if res: data = json.loads(res.group(0).lstrip('gallery: ').rstrip('siblingLis').strip().rstrip(',')) if data and 'sub_images' in data.keys(): sub_images = data.get('sub_images') images = [item.get('url') for item in sub_images] for image in images: download_image(image) return{ 'title': title, 'url': url, 'images': images }def download_image(url): print('下载:'+url) try: res = requests.get(url) if res.status_code == 200: # 直接调用保持图片,传入参数网页的二进制信息 save_iamge(res.content) # res.contenst是二进制信息,因为下载图片需要二进制。 return None except RequestException: print('详情页请求失败') return Nonedef save_iamge(content): # 构造保持路径, {0}为当前目录路径,{1}为md5生成值,避免重复下载,{2}为文件格式 file_path = '{0}/images/{1}.{2}'.format(os.getcwd(), md5(content).hexdigest(), 'jpg') print(file_path) if not os.path.exists(file_path): # 如果 路径文件不存在 就下载 with open(file_path, 'wb') as f: f.write(content) # 传入二进制信息 f.close()def main(offset): urls = get_index(offset, '街拍') for url in parse_index(urls): res = get_detail(url) parse_detail(res, url) # # 测试单个页面: # url = 'https://temai.snssdk.com/article/feed/index?id=3972873&subscribe=6768458493&source_type=24&content_type=2&create_user_id=6100&classify=2&adid=__AID__' # res = get_detail(url) # print(parse_detail(res, url))if __name__ == '__main__': # 传入翻页内容,每次offset变化20,因此0-10也每次*20 for i in range(0, 10): main(i*20)
阅读全文
0 0
- Python爬取今日头条搜索的照片。使用requests+正则表达式
- python3实现爬虫爬取今日头条上面的图片(requests+正则表达式+beautifulSoup+Ajax+多线程)
- 使用python-aiohttp爬取今日头条
- Python 淘宝商品价格爬取(requests库+正则表达式)
- 爬取今日头条图片
- python3.x 爬取今日头条
- 今日头条热点爬文章---python
- python:使用requests,bs4爬取mmjpg上的图片
- Python3爬取今日头条有关《人民的名义》文章
- Python使用Selenium + PhantomJS抓取动态网页:今日头条
- Requests+正则表达式爬取猫眼电影top100
- 今日头条的首页
- python爬今日头条(ajax分析)
- 爬今日头条文章
- Python爬取网页信息时,经常使用的正则表达式及方法
- python里使用正则表达式搜索单词
- requests和正则爬取猫眼的数据
- Python 爬取蜂鸟网的照片。。。
- centos7的系统时间设置
- 使用Rxjava2+Retrofit实现简单的快递查询
- 简单选择排序
- 心情平复,10月7日
- [LeetCode] ZigZag Conversion
- Python爬取今日头条搜索的照片。使用requests+正则表达式
- SpringBoot一些很实用的功能
- 中序线索化二叉树以及中序遍历线索化二叉树、倒中序遍历线索化二叉树
- 直接插入排序
- c3p0数据源配置抛出Could not load driverClass com.mysql.jdbc.Driver的解决方案
- Slim Span UVA
- django开发(6)配置url
- 希尔排序 插入排序的升级
- android的几种数据存储方式