I think I will give you some basic steps, that is, add a node of type "TEX_IMAGE", assign your image to it. therefore:
obj = bpy.context.active_object
# You can choose your texture size (This will be the de bake image)
image_name = obj.name + '_BakedTexture'
img = bpy.data.images.new(image_name,1024,1024)
#Due to the presence of any multiple materials, it seems necessary to iterate on all the materials, and assign them a node + the image to bake.
for mat in obj.data.materials:
mat.use_nodes = True #Here it is assumed that the materials have been created with nodes, otherwise it would not be possible to assign a node for the Bake, so this step is a bit useless
nodes = mat.node_tree.nodes
texture_node =nodes.new('ShaderNodeTexImage')
texture_node.name = 'Bake_node'
texture_node.select = True
nodes.active = texture_node
texture_node.image = img #Assign the image to the node
bpy.context.view_layer.objects.active = obj
bpy.ops.object.bake(type='DIFFUSE', save_mode='EXTERNAL')
img.save_render(filepath='C:\\TEMP\\baked.png')
#In the last step, we are going to delete the nodes we created earlier
for mat in obj.data.materials:
for n in mat.node_tree.nodes:
if n.name == 'Bake_node':
mat.node_tree.nodes.remove(n)
Avoid as much as possible to use bpy.ops, in this case, as you can see, it is easy to create an image with the methods bpy.data.images.new () Any blender object can be created with that method.
bpy.data.objects.new()
bpy.data.materials.new()
bpy.data.scenes.new()
...
...
bpy.ops it is good to use it only when you have no alternatives, as in this case with the bpy.ops.object.bake()
this allows you to create something, and assign it directly to a variable, as in the example of img = bpy.data.images.new()
So you don't have to go crazy to have access to it.
Another way for save the image is:
# Use filepath_raw and not filepath, by my experience is the best way
# This is without data refreshing,It shouldn't cause any problems
img.filepath_raw = 'C:\\TEMP\\baked.png'
img.save()