小姐姐退下吧 发表于 2020-7-31 18:19

python采集的图文如何保证图片的位置和原网页一样呢?

想采集一些新闻,新闻中既有文字又有图片,

然后我想将新闻的正文采集到数据库,

图片会保存到本地

如何保证图片的位置和原网页一样呢?

有没有大佬给个简单的例子?

rsnodame 发表于 2020-8-1 19:44

小姐姐退下吧 发表于 2020-8-1 14:36
首先感谢热心回复,我们还是以一个实例来说明吧,

比如这个网址:https://dy.163.com/article/FISL2VN ...

不要和p过不去{:301_997:},把文章正文部分的html源码完整保存就行了呀。
以这个网易新闻为例,分析网页元素可知
标题、发布日期、作者等,在 <div class="article_title"> 这个标签里,你已经定位到了;
正文、免责声明、评论、其它推荐等等,在 <div class="article_box"> 这个标签里。其实只要用bs把这个标签里的源码全部保存了就行。不过这样无关的内容有点多,可以更进一步;
在 <div class="article_box"> 这个标签下,正文其实在<div class="content" id="content" data-cover="">标签里头。
为了让代码足够强壮,可以先定位<div class="article_box">,再定位<div class="content" id="content" data-cover="">,这样定位出来的节点肯定就是完整的正文了
article_box = bsobj.find(name='div',class_='article_box')
article_body = article_box.find('div',class_='content',id='content')   # 完整的正文
然后就是处理img了。之前也提到的,遍历并修改img标签的src属性即可
first_img = article_body.img # 以第一个img标签举例
# <img src="http://dingyue.ws.126.net/2020/0731/b93a702fj00qebrax003kc000iy00xim.jpg"><br/></img>
first_img['src'] = '本地pic地址' # 修改src属性
# 可以尝试打印article_body.img,可以看到已经变为<img src="本地pic地址"><br/></img>

实际操作用.find_all()然后遍历即可。当然其中还有图片的本地保存、生成本地地址等过程,我就不赘述了。
最后就是把修改好的article_body 导出即可
output = str(article_body)
output即是图片地址已经修改过的、全部正文的html代码。你可以保存为文本文件后当做网页打开,也可以写到数据库里

收敛水 发表于 2020-7-31 22:30

是图片在那一段文字的位置吗?如果是这样只需要记录img标签引用的图片名,如果图片名不是唯一的就自己修改成一个唯一的图片吗,保存在本地的图片也改为这个图片名。

Jingk 发表于 2020-7-31 22:50

提取img 标签名加页面标题名 作为储存就好了啊

小姐姐退下吧 发表于 2020-7-31 23:13

Jingk 发表于 2020-7-31 22:50
提取img 标签名加页面标题名 作为储存就好了啊

有没有一个简单的示例啊 我用的是BeautifulSoup

pList = bsobj.find('div', attrs = {'class': 'entry-content'}).find_all('p')# 正文
    imgList = bsobj.find('div', attrs = {'class': 'entry-content'}).find_all('img') #所有图片

现在只是能单独把文字和图片都提取出来 如何保证插入数据库的时候 图片的位置在文中的位置和原来一样呢?

thepoy 发表于 2020-8-1 08:16

如果你保存到数据库中的是文本格式,你就无法实现这一点。你需要将整个html保存到数据库中,图片保存到本地后,替换掉img里的链接。如果需要,还可以通过源网站的css打开你爬取的内容,应该就是你想要的结果。

rsnodame 发表于 2020-8-1 09:41

不知道对于保存的格式,你有啥要求。。。如果pdf也可以,推荐一个现成的工具wkhtmltopdf
https://github.com/wkhtmltopdf/wkhtmltopdf/
直接命令行操作,效果一流。

如果是需要在本地保存成html网页的形式,那就是保存整个网页。如果网页框架比较有规律,可以进一步分析正文可以用哪个标签全部包括的,用bueatifulsoup定位那个标签,再做处理。你按所有p标签定位,肯定没法保留整个网页的段落结构。
保存图片同时还要在本地保存的html上正常显示就要复杂一点。最简单的,比如你已经定位了所有img标签,然后可以用beautifulsoup修改img标签的src属性,把图片地址修改成本地保存图片的地址。
beautifulsoup的官方示例:
soup = BeautifulSoup('<b class="boldest">Extremely bold</b>')
tag = soup.b

tag.name = "blockquote"
tag['class'] = 'verybold'
tag['id'] = 1
tag
# <blockquote class="verybold" id="1">Extremely bold</blockquote>

小姐姐退下吧 发表于 2020-8-1 14:36

rsnodame 发表于 2020-8-1 09:41
不知道对于保存的格式,你有啥要求。。。如果pdf也可以,推荐一个现成的工具wkhtmltopdf
https://github.c ...

首先感谢热心回复,我们还是以一个实例来说明吧,

比如这个网址:https://dy.163.com/article/FISL2VNN0519DH2H.html

我需要将标题、正文原封不懂得爬取到本地数据库,图片替换为本地的数据

那么 我现在的代码是这样的:

# -*- coding=utf-8 -*-

import requests
import bs4
import os
import datetime
import time

from urllib.request import urlopen

def fetchUrl(url):
    '''
    功能:访问 url 的网页,获取网页内容并返回
    参数:目标网页的 url
    返回:目标网页的 html 内容
    '''

    headers = {
      'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
      'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
    }

    r = requests.get(url,headers=headers)
    r.raise_for_status()
    r.encoding = r.apparent_encoding
    return r.text


def get_article_content():
    data_list = []
    pic_id = 0
    url = "https://dy.163.com/article/FISL2VNN0519DH2H.html"
    html = fetchUrl(url)
    # print(html)
    time.sleep(3)
    bsobj = bs4.BeautifulSoup(html,'html.parser')
    title = bsobj.find('div', attrs = {'class': 'article_title'}).find('h2').text# 标题
    pList = bsobj.find('div', attrs = {'id': 'content'}).find_all('p')# 正文
    imgList = bsobj.find('div', attrs = {'id': 'content'}).find_all('img') #所有图片
    content = ''
    pic_urls = ''
    for p in pList:
      content += p.text + '\n'
    for img in imgList:
      pic_url = img['src']
      pic_name = './pic_'+str(pic_id)+'.jpg'
      with open(pic_name, 'wb') as down_url: # 二进制创建并写入文件
            down_url.write(requests.get(pic_url).content)# 写出请求得到的img资源
      time.sleep(3)
      pic_urls += pic_name + '\n'
      pic_id += 1
    content += pic_urls #我现在是把图片全部都放到了正文后面 如何保持和原文章一致呢?
    print(title,content)


if __name__ == '__main__':
    get_article_content()


现在图片我是放到了文章内容的最后面,如何让图片保持和原文原有的位置呢?

小姐姐退下吧 发表于 2020-8-2 13:50

rsnodame 发表于 2020-8-1 19:44
不要和p过不去,把文章正文部分的html源码完整保存就行了呀。
以这个网易新闻为例,分析网页 ...

是我钻牛角了 被你说中了 我一直在和p过不去,:wwqwq 谢谢指导!这个直接插入数据库会带入一些不必要的样式 可能还需要进一步替换处理下。

rsnodame 发表于 2020-8-2 15:21

小姐姐退下吧 发表于 2020-8-2 13:50
是我钻牛角了 被你说中了 我一直在和p过不去, 谢谢指导!这个直接插入数据库会带入一些不必要的样 ...

beautifulsoup有删除、修改节点的功能,可以参考一下。不过删减样式肯定是体力活{:301_999:}
页: [1] 2
查看完整版本: python采集的图文如何保证图片的位置和原网页一样呢?