Здравствуйте ещё раз. Есть код, который выполняет парсинг с сайта в json. Код работает.
Хочу, чтобы данные с json были преобразованы в таблицу db. Находил много способов в Интернете, но там обязательно нужно было вводить код доступа в localhost. А я бы хотел, чтобы выполнялось без подключения. Написал код.
import requests
import json
from bs4 import BeautifulSoup
import re
from datetime import date, timedelta
import asposecells
import jpype
from openpyxl import Workbook
import pandas as pd
import mysql.connector
import sqlite3
PAGES_COUNT = 1
OUT_FILENAME = 'out2.json'
import warnings
warnings.filterwarnings("ignore")
def get_soup(url, **kwargs):
response = requests.get(url, **kwargs, verify=False)
if response.status_code == 200:
soup = BeautifulSoup(response.text, features='html.parser')
else:
soup = None
return soup
def crawl_products(pages_count):
urls = []
fmt = 'https://www.rfbr.ru/rffi/ru/contest?CONTEST_STATUS_ID=-1&CONTEST_TYPE=-1&CONTEST_YEAR=-1&page={page}'
for page_n in range(1, 1 + pages_count):
print('page: {}'.format(page_n))
page_url = fmt.format(page=page_n)
soup = get_soup(page_url)
if soup is None:
break
for tag in soup.select('.tr .link'):
href = tag.attrs['href']
url = 'https://www.rfbr.ru/rffi/ru/contest{}'.format(href)
urls.append((url, page_n))
return urls
def parse_products(urls):
data = []
for url in urls:
print('product: {}'.format(url[0]))
soup = get_soup(url[0])
if soup is None:
break
for j in soup.find_all("main", {"class": "template__main"}):
for jj in j.find_all("div", {"class": "sfc l-3 mt-5 mb-10 lh-xl"}):
ja = re.sub(r'[^\x00-\x7f]', r'', str(jj))
jo = re.sub(r'\<[^>]*\>', '', str(ja))
ji = re.sub(r'_', '', str(jo))
ju = re.sub(r' ', '', str(ji))
je = re.sub(r' :', '', str(ju))
jy = je[13:]
amount = jy
rponse = requests.get(url[0], verify=False)
sp = BeautifulSoup(rponse.text, "lxml")
document = {}
item = {}
dcs = sp(attrs={"class": "list-in article"})
for z in dcs:
document[z.h2.text] = list(z.ol.stripped_strings)
# document[z.h2.text] = tuple(z.ol.stripped_strings)
# в одну строку с разделителем запятая
for z in dcs:
document[z.h2.text] = ', '.join(z.ol.stripped_strings)
try:
article = [l.get_text(strip=True) for l in soup.find_all("p") if l.get_text(strip=True)]
art = str(article).replace("['", '').replace("']", '')
except:
article = [l.get_text(strip=True) for l in soup.find_all("h2") if l.get_text(strip=True)]
art = str(article).replace("['", '').replace("']", '')
for row in soup.select('td'):
cols = row.select('td')
cols = [c.text.strip() for c in cols]
name = [i.get_text(strip=True) for i in soup.find_all("h1") if i.get_text(strip=True)]
ame = str(name).replace("['", '').replace("']", '')
_page = f'?page={url[1]}'
p = get_soup(f'https://www.rfbr.ru/rffi/ru/contest{_page}')
for img_td in p.select('.tr'):
image = img_td.select_one("img").get('alt')
item['Название'] = ame
item['Статус'] = image
item['Время окончания приема заявок'] = amount
item['Полное описание условий конкурса'] = art
item['Документы'] = document
data.append(item)
return data
def dump_to_json(filename, data, **kwargs):
kwargs.setdefault('ensure_ascii', False)
kwargs.setdefault('indent', 1)
with open(OUT_FILENAME, 'w', encoding="utf-8") as f:
json.dump(data, f, **kwargs)
def main():
urls = crawl_products(PAGES_COUNT)
data = parse_products(urls)
dump_to_json(OUT_FILENAME, data)
with open(OUT_FILENAME, 'w', encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=1)
with open(OUT_FILENAME, encoding='utf-8') as de:
mate = json.load(de)
df = pd.DataFrame(mate)
conn = sqlite3.connect("data.db")
c = conn.cursor()
df.to_sql("tablename",conn,if_exists='replace')
if __name__ == '__main__':
main()
И у меня выходит вот такая ошибка:
sqlite3.ProgrammingError: Error binding parameter 6: type 'dict' is not supported
Что нужно исправить?