惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
H
Hacker News: Front Page
P
Palo Alto Networks Blog
T
ThreatConnect
Apple Machine Learning Research
Apple Machine Learning Research
博客园_首页
T
True Tiger Recordings
P
Privacy & Cybersecurity Law Blog
B
Blog
IT之家
IT之家
Last Week in AI
Last Week in AI
F
Full Disclosure
Hacker News: Ask HN
Hacker News: Ask HN
C
Comments on: Blog
Microsoft Azure Blog
Microsoft Azure Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Microsoft Security Blog
Microsoft Security Blog
博客园 - 【当耐特】
N
News and Events Feed by Topic
NISL@THU
NISL@THU
腾讯CDC
雷峰网
雷峰网
Security Latest
Security Latest
李成银的技术随笔
M
Microsoft Research Blog - Microsoft Research
L
LangChain Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
Check Point Blog
Y
Y Combinator Blog
Recent Announcements
Recent Announcements
博客园 - Franky
N
News | PayPal Newsroom
V
V2EX
A
About on SuperTechFans
The Register - Security
The Register - Security
月光博客
月光博客
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Google Online Security Blog
Google Online Security Blog
MyScale Blog
MyScale Blog
Cisco Talos Blog
Cisco Talos Blog
Vercel News
Vercel News
WordPress大学
WordPress大学
C
Cyber Attacks, Cyber Crime and Cyber Security
The Hacker News
The Hacker News
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
爱范儿
爱范儿
A
Arctic Wolf
L
LINUX DO - 最新话题
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

博客园 - pmh905001

爬虫-今日头条我的收藏-反爬虫分析(六) pycharm的没落,vs code的兴起 爬虫-今日头条我的收藏-增量式下载网页内容(五) 爬虫-今日头条我的收藏-增量式导入到Elastic Search(四) 今日头条源代块一行代码很长情况下的拖动问题 爬虫-今日头条我的收藏-增量式导入到mongodb(三) openpyxl一个bug 爬虫-今日头条我的收藏(一) pystray被隐藏菜单项显示出来的问题 pyinstaller生成的exe程序使用使用默认程序打开execel文件 pyinstaller生成的exe文件的所在的工作目录问题 windows下python的keyboard库在锁屏之后再次登陆快捷键(热键)失效问题 pyinstaller 报错ImportError: No module named _bootlocale windows下gitbash 鼠标左键选中文字自动自行终止命令 ctrl+c ^C spring-security 如何使用用户名或邮箱登录 tomcat jndi context.xml的特殊字符转义问题 struts2的优缺点以及如何改造 jetty-maven-plugin 版本导致jetty启动失败问题 Eclipse下pom.xml的提示 Cannot access defaults field of Properties
爬虫-今日头条我的收藏-增量式(二)
pmh905001 · 2023-12-19 · via 博客园 - pmh905001

背景:

能够全量爬取今日头条我的收藏内容之后,新收藏的内容依然希望能够保存到新文件中。

思路:

  • 每次都全量爬取数据太耗时,增量式爬取可以节省时间。但逻辑上显然要复杂一些。关键的问题是要找到断点的位置。
  • 取消收藏的影响:爬虫旧文件用户收藏的链接有可能被取消收藏。所以在断点位置的判断上不能只取一条数据的id作为参考,考虑取连续100条的我的收藏id作为判断基准,这样即便用户偶尔取消收藏几条,依然能够准确找到断点。
  • 增量式功能可以覆盖全量下载我的收藏。第一次下载由于没有断点,需要全量下载。后续由于已经有下载的文件作为参照物,只需要从参照物继续下载。
  • 每次运行增量爬虫,如果有新内容,则新增一个文件,文件格式:myfavorites-年月日-时分秒.txt。如果没有新内容,不需要新增文件。

实现:

  • 代码参考这里:https://github.com/pmh905001/myfavorite/blob/master/toutiao/increasmentdownload.py .主代码如下:
    def increasement_download():
        url, headers = read_curl()
        latest_ids_downloaded = latest_ids_from_file()
        page = get_page(url, headers, 0, latest_ids_downloaded)
        try_num = 0
        file_name = f'myfavorites-{time.strftime("%Y%m%d-%H%M%S")}.txt'
        while page['has_more']:
            try_num += 1
            max_behot_time = page['next']['max_behot_time']
            write_page(page, file_name)
            sleep_time = random.randint(1, 10)
            print(f'-------------------------------------------page number: {try_num}, sleep {sleep_time} seconds')
            time.sleep(sleep_time)
            page = get_page(url, headers, max_behot_time, latest_ids_downloaded)
        else:
            write_page(page, file_name)
  • 从断点处按照有新到旧的id需要获取最多100条,这种情况下需要遍历所有myfavorites-年月日-时分秒.txt的文件且需要倒序排列,依次读取id直到100条(用户可以自己调整)。参考latest_ids_from_file()
    def latest_ids_from_file():
        ids = []
        my_favorite_files = sorted([f for f in os.listdir('.') if f.startswith('myfavorites-')], reverse=True)
        for file_name in my_favorite_files:
            with open(file_name, 'r', encoding='utf-8') as f:
                page: dict = json.loads(f.readline())
                if page.get('data'):
                    for record in page['data']:
                        if len(ids) <= 100:
                            ids.append(record['id'])
                        else:
                            return ids
        return ids
  •  在获取每页的数据之后,需要找到断点,把冗余的数据给删除。重置has_more=False。参考get_page()方法
    def get_page(url, headers, max_behot_time=0, latest_ids_downloaded=[]):
        url = replace_url_param(url, 'max_behot_time', max_behot_time)
        response = requests.get(url, headers=headers)
        page: dict = response.json()
        if page.get('data'):
            for index, record in enumerate(page.get('data')):
                if record['id'] in latest_ids_downloaded:
                    page['data'] = page['data'][:index]
                    page['has_more'] = False
  •  在写文件的时候,如果页数据收藏列表如果为空,则不写入文件。参考write_page()
    def write_page(page, file_name):
        if not page.get('data'):
            return
        with open(file_name, 'a', encoding='utf-8') as fp:
            page_info = json.dumps(page, ensure_ascii=False)
            fp.write(page_info)
            fp.write('\n')
    
        for item in page['data']:
            try:
                print(f"{item['id']}: {item['title']}   => {item['share_url']}")
            # Fixme: UnicodeEncodeError
            except UnicodeEncodeError:
                logging.exception('occurred exception when print')
  • 代码写的比较粗糙,还需要找时间重构。这里仅供参考