Как установить print () в docx python - PullRequest
0 голосов
/ 03 августа 2020

У меня есть код, который получает информацию о селене, и мне нужно распечатать эту информацию в docx, но по шаблону. Здесь я получаю информацию с помощью print () (для установки некоторой части)

Старшая школа Стуйвесант

Общая информация

Название школы: Stuyvesant High School, дневная Заказчик: Мистер Эри c Контрерас Электронная почта директора: ECONTRE@SCHOOLS.NYC.GOV Тип: Обычная школа Градус: 9–12 Адрес: 345 Chambers Street, New York, NY 10282

Я распечатываю эту информацию в консоли, но мне нужно распечатать эту информацию в docx.

Здесь часть кода, где я печатаю:

from selenium import webdriver
from selenium.common.exceptions import NoSuchElementException
import openpyxl
import docx
from docx.shared import Pt

List = []
wb = openpyxl.load_workbook('D:\INSPR\Rating_100_schools\Top-100.xlsx')
sheet = wb['RI']
tuple(sheet['A1':'A100']) # Get all cells from A1 to A100.
for rowOfCellObjects in sheet['A1':'A100']:
    for cellObj in rowOfCellObjects:
        List.append(cellObj.value)

School_list_result = []
State = sheet.title

driver = webdriver.Chrome(executable_path='D:\chromedriver') #any path

def check_xpath(xpath):
        try:
            element = driver.find_element_by_xpath(xpath)
            School_list_result.append(element.text)
        except NoSuchElementException:
            School_list_result.append("No data.")
    
def check_text(partial_link_text):
        try:
            element_text = driver.find_element_by_partial_link_text(partial_link_text)
            School_list_result.append(element_text.get_attribute("href"))
        except NoSuchElementException:
            School_list_result.append("No data.")
            
def check_click(clicker):
        try:
            element_click = driver.find_element_by_partial_link_text(clicker)
            element_click.click()
        except NoSuchElementException:
            print("No click.")
            
def get_url(url, _xpath, send_keys):
    driver.get(url)
    try:
            _element = driver.find_element_by_xpath(_xpath)
            _element.clear()
            driver.implicitly_wait(10)
            _element.send_keys(schools, send_keys)
            _element.send_keys(u'\ue007')
            driver.implicitly_wait(10)
    except NoSuchElementException:
            print("No data.")

for schools in List[98:100]:
    
    #-----------------------------------------GREAT SCHOOLS-------------------------------------------
    get_url("https://www.google.com/", '//*[@id="tsf"]/div[2]/div[1]/div[1]/div/div[2]/input'," " + State + " greatschools")
    _clicker = driver.find_element_by_xpath('//*[@id="rso"]/div[1]/div/div[1]/a/h3').click()
    
    check_xpath('//*[@id="hero"]/div/div[1]/h1') #School Name
    
    check_xpath('/html/body/div[6]/div[8]/div/div[1]/div/div/div[2]/div[1]/div[2]/span[1]') #Principal
    
    check_text('Principal email') #Principal’s E-mail
    
    check_xpath('//*[@id="hero"]/div/div[2]/div[2]/div[3]/div[2]') #Grade Span
    
    check_xpath('//*[@id="hero"]/div/div[2]/div[1]/div[1]/div[1]/div[1]/a/div/span[2]') #Address
    
    check_xpath('/html/body/div[6]/div[8]/div/div[1]/div/div/div[2]/div[2]/span/a') #Phone
   
    check_text('Website') #Website
   
    check_xpath('//*[@id="hero"]/div/div[2]/div[1]/div[1]/div[1]/div[2]/a') #Associations/Communities
   
    check_xpath('//*[@id="hero"]/div/div[2]/div[2]/div[1]/div/a/div[1]/div') #GreatSchools Rating
 
    check_xpath('//*[@id="Students"]/div/div[2]/div[1]/div[2]') #Enrollment by Race/Ethnicity
            
    #-----------------------------------------NCES-------------------------------------------
    
    driver.implicitly_wait(10)
    get_url("https://nces.ed.gov/search/index.asp?q=&btnG=Search#gsc.tab=0", '//*[@id="qt"]', " " + State)
    check_click('Search for Public Schools - ')
    driver.implicitly_wait(10) 
    
    check_xpath('/html/body/div[1]/div[3]/table/tbody/tr[4]/td/table/tbody/tr[7]/td[1]/font[2]') #School type
    
    check_xpath('/html/body/div[1]/div[3]/table/tbody/tr[4]/td/table/tbody/tr[7]/td[3]/font') #Charter
    
    check_xpath('/html/body/div[1]/div[3]/table/tbody/tr[12]/td/table/tbody/tr[3]/td/table/tbody/tr[2]/td/table/tbody')
    #Enrollment by Gender
    
    check_xpath('/html/body/div[1]/div[3]/table/tbody/tr[12]/td/table/tbody/tr[1]/td/table/tbody/tr[2]') #Enrollment by Grade
    
    #-----------------------------------------USNEWS-------------------------------------------
    driver.implicitly_wait(10)
    url = "https://www.usnews.com/education/best-high-schools/new-york/rankings"
    driver.get(url)
    check_click(schools)
    driver.implicitly_wait(10)
    
    check_xpath('//*[@id="app"]/div/div/div/div[1]/div/div/div[2]/div[1]/div[2]/p[3]') #U.S.News Rankings
            
    #-----------------------------------------PUBLIC REVIEW-------------------------------------------
    driver.implicitly_wait(10)
    get_url("https://www.google.com/", '//*[@id="tsf"]/div[2]/div[1]/div[1]/div/div[2]/input', " " +  State + " publicschoolreview")
    clicker = driver.find_element_by_partial_link_text('(2020)').click()
    driver.implicitly_wait(10)
    
    check_xpath('//*[@id="quick_stats"]/div/div[2]/ul/li[2]/strong') #Total # Students
   
    check_xpath('//*[@id="total_teachers_data_row"]/td[2]') #Full-Time Teachers
        
    check_xpath('//*[@id="quick_stats"]/div/div[2]/ul/li[3]/strong') #Student/Teacher Ratio
        
    #-----------------------------------------PRINT INFOFMATION-------------------------------------------
    
    print("         ---------------------------------------------------------------"+"\n",
          "                              \033[1m", schools,"\033[0m"+"\n",
          "         ---------------------------------------------------------------"+"\n",
          "                              \033[1mGeneral Information\033[0m        "+"\n",
          "\033[1mSchool Name:\n\033[0m",School_list_result[0]+"\n",
          "\033[1mPrincipal:\n\033[0m",School_list_result[1]+"\n",
          "\033[1mPrincipal’s E-mail:\n\033[0m",School_list_result[2]+"\n",
          "\033[1mType:\n\033[0m",School_list_result[10]+"\n",
          "\033[1mGrade Span:\n\033[0m",School_list_result[3]+"\n",
          "\033[1mAddress:\n\033[0m",School_list_result[4]+"\n",
          "\033[1mPhone:\n\033[0m",School_list_result[5]+"\n",
          "\033[1mWebsite:\n\033[0m",School_list_result[6]+"\n",
          "\033[1mAssociations/Communities:\n\033[0m",School_list_result[7]+"\n",
          "\033[1mGreatSchools Summary Rating:\n\033[0m",School_list_result[8]+"\n",
          "\033[1mU.S.News Rankings:\n\033[0m",School_list_result[14]+"\n",
          "                              \033[1mSchool Details\033[0m"+"\n",
          "\033[1mTotal # Students:\n\033[0m",School_list_result[15]+"\n",
          "\033[1mFull-Time Teachers:\n\033[0m",School_list_result[16]+"\n",
          "\033[1mStudent/Teacher Ratio:\n\033[0m",School_list_result[17]+"\n",
          "\033[1mCharter:\n\033[0m",School_list_result[11]+"\n",
          "\033[1mMagnet: \n\033[0m","No""\n",
          "                              \033[1mEnrollment Data\033[0m"+"\n",
          "\033[1mEnrollment by Race/Ethnicity: \n\033[0m",School_list_result[9]+"\n",
          "\033[1mEnrollment by Gender: \n\033[0m",School_list_result[12]+"\n",
          "\033[1mEnrollment by Grade: \n\033[0m",School_list_result[13]+"\n",
          ()
         )
    
    
    print()
    
    School_list_result.clear()

Что мне нужно: распечатать этот результат не в консоль по шаблону, а в docx по шаблону. И еще: если вы знаете, как не использовать индексацию (например: School_list_result [0] ), сообщите мне.

1 Ответ

1 голос
/ 03 августа 2020

Я предполагаю, что вы работаете в операционной системе windows, как и я, и знаете, как загрузить python пакеты:

  1. Установить модули docx и python-docx (они разные, убедитесь, что вы установили оба)

  2. используйте следующий код:

School_list_result = [
    "Stuyvesant High School",
    "Mr. Eric Contreras",
    "ECONTRE@SCHOOLS.NYC.GOV",
    "Regular school",
    "9-12",
    "345 Chambers Street, New York, NY 10282",
]

headers = [
    "School Name: ",
    "Principal: ",
    "Principal's Email: ",
    "Type: ",
    "Grade Span: ",
    "Address: ",
]


def print_into_one_doc():
    import os
    from docx import Document
    from docx.shared import RGBColor
    from docx.shared import Pt
    from docx.enum.text import WD_PARAGRAPH_ALIGNMENT

    # after you create a docx file, make sure you double click to open it, write some stuff, press ctrl + s, delete what you have written, press ctrl + s, close the document
    # delete what you have written. Otherwise python-docx reports a Package Not Find Error. 
    p = input('hold shift key right click, copy and paste the file path of docx here: ')
    if p[0] == '"' or p[0] == "'":
        # validate path
        p = p[1:-1]
    p = os.path.abspath(p)
    doc = Document(p)
    h = doc.add_paragraph()
    # make title align to center
    h.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
    r = h.add_run(School_list_result[0])
    # set title color
    r.font.color.rgb = RGBColor(54, 95, 145)
    # set title size
    r.font.size = Pt(36)
    doc.add_paragraph('\n')
    su = doc.add_paragraph()
    ru = su.add_run('General Information')
    ru.font.size = Pt(30)
    for i, d in enumerate(headers):
        sp = doc.add_paragraph()
        rp = sp.add_run(headers[i])
        rp.bold = True
        rp.font.size = Pt(23)
        sm = doc.add_paragraph()
        rm = sm.add_run(School_list_result[i])
        rm.font.size = Pt(22)
        rm.italic = True
    doc.add_page_break()
    doc.save(p)


print_into_one_doc()

Если у вас есть список, содержащий School_list_result, выполните итерацию по нему, вот пример:
List_of_school_list_result = [
    [
        "Stuyvesant High School",
        "Mr. Eric Contreras",
        "ECONTRE@SCHOOLS.NYC.GOV",
        "Regular school",
        "9-12",
        "345 Chambers Street, New York, NY 10282",
    ],
    [
        "Great Lake College",
        "Mr. Jason Madunic",
        "MADUNIC@SCHOOLS.VIC.GOV",
        "Public school",
        "6-12",
        "167A High Street, Melbourne, VIC 3228",
    ],
]

headers = [
    "School Name: ",
    "Principal: ",
    "Principal's Email: ",
    "Type: ",
    "Grade Span: ",
    "Address: ",
]


def print_all_into_one_doc():
    import os
    from docx import Document
    from docx.shared import RGBColor
    from docx.shared import Pt
    from docx.enum.text import WD_PARAGRAPH_ALIGNMENT

    # after you create a new docx file, double click to open it, write some stuff, press ctrl + s, delete what you have written, press ctrl + s, close the document
    # Otherwise python-docx reports a Package Note Find Error. 
    p = input('hold shift key right click, copy and paste the file path of docx here: ')
    if p[0] == '"' or p[0] == "'":
        # validate path
        p = p[1:-1]
    p = os.path.abspath(p)
    doc = Document(p)
    # iterate List of all school
    for j in List_of_school_list_result:
        h = doc.add_paragraph()
        # make title align to center
        h.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
        r = h.add_run(j[0])
        # set title color: you can adjust any color of title here 
        r.font.color.rgb = RGBColor(54, 95, 145)
        # set title size
        r.font.size = Pt(36)
        doc.add_paragraph('\n')
        su = doc.add_paragraph()
        ru = su.add_run('General Information')
        ru.font.size = Pt(30)
        for i, d in enumerate(headers):
            sp = doc.add_paragraph()
            rp = sp.add_run(headers[i])
            rp.bold = True
            rp.font.size = Pt(23)
            sm = doc.add_paragraph()
            rm = sm.add_run(j[i])
            rm.font.size = Pt(22)
            rm.italic = True
        doc.add_page_break()
    doc.save(p)


print_all_into_one_doc()

Давайте упростим, вам нужно сделать следующее:

  1. создать список с именем List_of_school_list_result, сбросить ваши данные, каждая из них должна быть одной единственной записью определенной школы.
  2. в любом месте, создать новый файл docx, дважды щелкните, чтобы открыть его, напишите что-нибудь, нажмите ctrl + s, удалите то, что вы написали, нажмите ctrl + s, закройте документ.
  3. go в каталог, где находится ваш файл docx, удерживайте Shift , щелкните правой кнопкой мыши, скопируйте как путь.
  4. убедитесь, что установлены docx и python-docx, запустите код, когда вас попросят ввести путь, вставьте его из буфера обмена. (Убедитесь, что вы используете абсолютный путь, который представляет собой полный каталог с root c, относительный путь может не работать).

PS: причина, по которой вам нужно открыть docx после создания, заключается в том, что файл docx Microsoft Word 2005+ имеет 3 режима. во-первых, если он новый после создания, он в двоичном формате. во-вторых, если мы откроем его для редактирования, он сгенерирует файл $ cache.docx, скрытый в каталоге того же уровня, для обеспечения производительности и защиты данных на случай cra sh. в-третьих, если он отредактирован и сохранен, формат будет преобразован в XML, который РЕДАКТИРУЕТСЯ с использованием модуля python-docx.

PS: класс Result ниже обеспечивает четкий способ создания List_of_school_list_result:

class Result:
    def __init__(self, length):
        self.l = length
        self.res = []
        self.col = []

    def push(self, string):
        self.col.append(string)
        if(len(self.col) == self.l):
            self.res.append(self.col)
            self.col = []

    def publish(self):
        return self.res


r = Result(6) # pass in the length of the headers, then all you need, is to call `r.push()` over and over again. after that, assign it to `List_of_school_list_result`
r.push('school name 1')
r.push('principal name 1')
r.push('principal email 1')
r.push('school type 1')
r.push('grad span 1')
r.push('address 1')

r.push('school name 2')
r.push('principal name 2')
r.push('principal email 2')
r.push('school type 2')
r.push('grad span 2')
r.push('address 2')
List_of_school_list_result = r.publish()

Полная версия кода:

headers = [
    "School Name: ",
    "Principal: ",
    "Principal's Email: ",
    "Type: ",
    "Grade Span: ",
    "Address: ",
]

class Result:
    def __init__(self, length):
        self.l = length
        self.res = []
        self.col = []

    def push(self, string):
        self.col.append(string)
        if(len(self.col) == self.l):
            self.res.append(self.col)
            self.col = []

    def publish(self):
        return self.res


r = Result(len(headers))

# call r.push() over and over again, until all the string data is passed in.

''' for example
r.push('school name 1')
r.push('principal name 1')
r.push('principal email 1')
r.push('school type 1')
r.push('grad span 1')
r.push('address 1')

r.push('school name 2')
r.push('principal name 2')
r.push('principal email 2')
r.push('school type 2')
r.push('grad span 2')
r.push('address 2')
'''

List_of_school_list_result = r.publish()


def print_all_into_one_doc():
    import os
    from docx import Document
    from docx.shared import RGBColor
    from docx.shared import Pt
    from docx.enum.text import WD_PARAGRAPH_ALIGNMENT

    # after you create a new docx file, double click to open it, write some stuff, press ctrl + s, delete what you have written, press ctrl + s, close the document
    # Otherwise python-docx reports a Package Note Find Error. 
    p = input('hold shift key right click, copy and paste the file path of docx here: ')
    if p[0] == '"' or p[0] == "'":
        # validate path
        p = p[1:-1]
    p = os.path.abspath(p)
    doc = Document(p)
    # iterate List of all school
    for j in List_of_school_list_result:
        h = doc.add_paragraph()
        # make title align to center
        h.paragraph_format.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
        r = h.add_run(j[0])
        # set title color: you can adjust any color of title here 
        r.font.color.rgb = RGBColor(54, 95, 145)
        # set title size
        r.font.size = Pt(36)
        doc.add_paragraph('\n')
        su = doc.add_paragraph()
        ru = su.add_run('General Information')
        ru.font.size = Pt(30)
        for i, d in enumerate(headers):
            sp = doc.add_paragraph()
            rp = sp.add_run(headers[i])
            rp.bold = True
            rp.font.size = Pt(23)
            sm = doc.add_paragraph()
            rm = sm.add_run(j[i])
            rm.font.size = Pt(22)
            rm.italic = True
        doc.add_page_break()
    doc.save(p)


print_all_into_one_doc()
...