今日头条的网页是通过AJAX加载的所以如果单纯的复制网页是无法查看到内容的,只能看到一堆字典形式HTML代码。
这里发现URL的参数共有offset,format,keyword,autoload,count,cur_tab,from,这七种。
往下翻,在Query String Parameters中就能发现这些参数
往下翻,查看新的AJAX,点开NETWORK对比Query String Parameters,会发现只有offset发生了变化
再回过头观察Query String Parameters 和requests.URL。会发现从https://www.toutiao.com/search_content/?
后开始参数都是按顺序拼接的。
import requests,json
from bs4 import BeautifulSoup
from requests.exceptions import RequestException
def get_page():
url = 'https://www.toutiao.com/search_content/?'
params={
'offset':' 0',
'format': 'json',
'keyword': '街拍',
'autoload':'true',
'count': '20',
'cur_tab': '1',
'from': 'search_tab',
}
#requests自带params参数能够补全URL可代替urllib.urlopen()的拼接
response = requests.get(url,params=params)
try:
if response.status_code == 200:
#如果状态码为200(即响应成功)则返回json格式的响应内容
#在requests中自带json()方法
return response.json()
else:
return None
except RequestException as f:
return f
def main():
html = get_page()
#输出响应内容
print(html)
if __name__ == '__main__':
main()
返回的结果如下
返回了一堆杂乱的json代码,但是chrome功能十分强大,自动帮整理。点开Preview,需要的东西全在data中
这次只取标题和图片链接,如果你愿意,还可以通过media_url爬取它所有文章的内容
先取标题,通过打印出的标题会发现有的标题为空。
def parse_page(html):
data =html.get('data')
for item in data:
title = item.get('title')
print(title)
没有标题的话肯定就不存在有内容,所以需要做一个判断,标题是否为空。
def parse_page(html):
data =html.get('data')
for item in data:
title = item.get('title')
# print(title) 打印出标题
if title is not None:
for url in item.get('image_list'):
#yield 返回,并生成一个生成器
yield{
'title':title,
'url':url
}
因为生成了一个生成器想要查看内容必须循环。
def main():
html = get_page()
#输出响应内容
# print(html)
page = parse_page(html)
for i in page:
print(i)
查看我们打印的内容会发现url很奇怪,我们得到了一个字典形式的不完全的URL,通过dict.get()方法得到值并补全代码
'url':'https:'+url.get('url')
再次打印,就出现了我们想要的结果
def save_image(img_list):
#首先判断是否存在该文件夹,如果没有title文件夹 ,则创建一个文件夹
if not os.path.exists(img_list.get('title')):
os.mkdir(img_list.get('title'))
try:
response = requests.get(img_list.get('url'))
#通过hash的md5的算法,防止出现重复名
haxi = md5(response.content).hexdigest()
file_path = '{0}/{1}.{2}'.format(img_list.get('title'), haxi, 'jpg')
if response.status_code == 200:
with open((file_path),'wb')as f:
f.write(response.content)
print('图片名:{0},图片链接:{1}'.format(img_list.get('title'),img_list.get('url')))
else:
print('已经下载图片',file_path)
except :
print('下载错误')
这是只是爬取第一页,如果想要爬取更多,只需要将params的的offset作为一个参数,修改一下就可以了。
def main():
for i in range(5):
offset = i *20
html = get_page(offset)
import requests,json
from bs4 import BeautifulSoup
from requests.exceptions import RequestException
import os
from hashlib import md5
def get_page(offset):
url = 'https://www.toutiao.com/search_content/?'
params={
'offset':offset,
'format': 'json',
'keyword': '街拍',
'autoload':'true',
'count': '20',
'cur_tab': '1',
'from': 'search_tab',
}
#requests自带params参数能够补全URL可代替urllib.urlopen()的拼接
response = requests.get(url,params=params)
try:
if response.status_code == 200:
#如果状态码为200(即响应成功)则返回json格式的响应内容
#在requests中自带json()方法
return response.json()
else:
return None
except RequestException as f:
return f
#解析内容
def parse_page(html):
data =html.get('data')
for item in data:
title = item.get('title')
# print(title) 打印出标题
if title is not None:
for url in item.get('image_list'):
#yield 返回,并生成一个生成器
yield{
'title':title,
'url':'https:'+url.get('url')
}
def save_image(img_list):
#首先判断是否存在该文件夹,如果没有title文件夹 ,则创建一个文件夹
if not os.path.exists(img_list.get('title')):
os.mkdir(img_list.get('title'))
try:
response = requests.get(img_list.get('url'))
#通过hash的md5的算法,防止出现重复名
haxi = md5(response.content).hexdigest()
file_path = '{0}/{1}.{2}'.format(img_list.get('title'), haxi, 'jpg')
if response.status_code == 200:
with open((file_path),'wb')as f:
f.write(response.content)
print('图片名:{0},图片链接:{1}'.format(img_list.get('title'),img_list.get('url')))
else:
print('已经下载图片',file_path)
except :
print('下载错误')
def main():
for i in range(5):
offset = i *20
html = get_page(offset)
#输出响应内容
# print(html)
page = parse_page(html)
for img_list in page:
save_image(img_list)
if __name__ == '__main__':
main()
这是第一次尝试抓取的时候,发现dict中并没有'data' 这个键。我查找了很久,终于发现有一个‘html'的键,所对应的值为整个HTML页面
因为只是测试,所以只爬取了一页,也没有做状态码的判断
import requests
from bs4 import BeautifulSoup
import os
from hashlib import md5
def get_one_page(offset):
headers = {
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.75 Safari/537.36'
}
params={
'offset': offset,
' format': 'json',
'keyword': ' 街拍',
'autoload': 'true',
'count': '20',
'cur_tab': '1',
}
url = 'https://www.toutiao.com/search_content/?'
response = requests.get(url,headers=headers,params=params)
if response.status_code==200:
return response.json()
return None
def parse_page(html):
data = html.get('html')
soup =BeautifulSoup(data,'lxml')
body=soup.select('section')
for i in body:
title = i.select('.line3')[0].string
if title is not None:
images=i.select('.list_img_holder img')
for image in images:
yield {
'title':title,
'image':image['src']
}
def save(page):
if not os.path.exists(page.get('title')):
os.mkdir(page.get('title'))
try :
response =requests.get(page.get('image'))
i = md5(response.content).hexdigest()
file_path = '{0}/{1}.{2}'.format(page.get('title'), i, 'jpg')
if response.status_code==200:
with open(file_path,'wb')as f:
f.write(response.content)
else:
print('Already Downloaded',file_path)
except :
print('file_path not save image')
def main():
offset = 0
html = get_one_page(offset)
print(html)
k=parse_page(html)
for page in k:
save(page)
if __name__ == '__main__':
main()