Создание базы данных ссылок с использованием sqlite на python - PullRequest
0 голосов
/ 09 марта 2020

Я написал следующий код, где я могу проследить начальную страницу до двух новых страниц и повторить этот процесс для 4 уровней, чтобы записать все URL-адреса с этих страниц. Я хочу создать базу данных всех ссылок, с которыми я столкнулся. Если я посетил страницу (ie следовал за ней, чтобы получить доступ к дополнительным ссылкам), я хочу записать 1 для этой ссылки и 0, если я не посещал страницу.

    def getlinks(xurl):
     # given a Wikipedia article url,
     # return all links on that page to Wikipedia articles
     # (really should add error checking)
    from urllib.request import urlopen
    from bs4 import BeautifulSoup
    import re

    xlinks = [] # initialize list of links
    hpage = urlopen(xurl) # read/open page
    bs = BeautifulSoup(hpage, 'html.parser') # parse page

     # find all links in div named 'bodyContent'
     # such that they start with '/wiki/' and contain no colon
    for link in bs.find('div', {'id':'bodyContent'}).find_all('a',
href=re.compile('^(/wiki/)((?!:).)*$')):
        if 'href' in link.attrs:
            # make the url complete and add to list
            xlinks.append('https://en.wikipedia.org{}'.format(link.attrs['href']))
    return xlinks # return list of urls

maxlevel = 4 # levels deep to follow

# branches to follow from each page on each level before the last
numbranches = 2
tasks = [] # initialize task list
mastlinks = set() # initialize master set of urls
iurl = 'https://en.wikipedia.org/wiki/Kevin_Bacon' # first page
ilevel = 1 # first (top) level
mastlinks.add(iurl) # add first page to master set

# add current level and page to tasks
tasks.append((ilevel, iurl))

import sqlite3
import csv
import os

visited = 0

db_connection = sqlite3.connect('dd5.db')
cursor = db_connection.cursor()
cretab = '''CREATE TABLE IF NOT EXISTS links (link TEXT PRIMARY KEY, visited BIT)'''
cursor.execute(cretab)


for ix in range(40): # do no more than 40 pages
    if not tasks: # if no more tasks, we're done
        break

    # remove next task level, url from end of task list
    level, url = tasks.pop()
    print('\n', ix, 'level', level, url)
    visited = 1
    links = getlinks(url) # get links from current %page
    cursor.execute("INSERT OR IGNORE INTO links VALUES (?, ?)", (links, visited))
    print(len(links), 'article links')
    ulinks = set(links)
    print(len(ulinks), 'unique article links')
    newlinks = ulinks.difference(mastlinks)
    mastlinks = mastlinks.union(newlinks)
    print(len(newlinks), 'new unique article links')
    linklist = list(newlinks)
    cursor.execute("UPDATE links SET visited=? WHERE link=?", (visited, links))
    print('sample links:')
    for link in linklist[:10]:
        print(link)
    if level < maxlevel:
        for link in linklist[:numbranches]:
            print('following', link)

            # add next level link to tasks
            tasks.append((level + 1, link))

Я получаю сообщение «InterfaceError: Ошибка привязки параметра 0 - возможно, неподдерживаемый тип». Ошибка. Я также не уверен, что мое размещение для кода, связанного с sqlite, является правильным, так как я новичок в этой области. Не могли бы вы помочь? Спасибо!

1 Ответ

0 голосов
/ 09 марта 2020

Ну, links это список. Используя .execute(), вы не можете INSERT или UPDATE со списком.

Вы можете l oop над этим списком:

for link in links:
    cursor.execute("INSERT OR IGNORE INTO links VALUES (?, ?)", (link, visited))

Другим потенциальным решением является использование .executemany(), который вы можете использовать следующим образом:

to_insert = []
for link in links:
    to_insert.append((link,visited))
cursor.executemany("INSERT OR IGNORE INTO links VALUES (?, ?)", to_insert)

Аналогичная проблема существует с вашим кодом UPDATE, и приведенная выше информация относится и к этому запросу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...