Automating sequence download from Wormbase I'm working on the C. elegans model organism, for which there exists an online biological information database: Wormbase.

I'm able to manually search for a transcript (say "K06C4.12") and this gets me the following URL:
http://www.wormbase.org/species/c_elegans/cds/K06C4.12

Say I have this transcript ID: "F08G2.2". I guess that I can form a valid similar URL, as follows:
http://www.wormbase.org/species/c_elegans/cds/F08G2.2

Indeed, it works as expected.

Now, I would like to go further and be able to download in an automated way what can be obtained by clicking on one of the "download" buttons in the "Sequence" section of the above pages. More specifically, I'm interested in the "spliced + UTR" and "conceptual translation" fasta sequences. 

If I use the DOM inspector in Firefox (Shift-Ctrl-C), I can locate things like the following:

&lt;div class="button ui-corner-all generate-file-download sequence-download"&gt;
    &lt;span class="ui-icon ui-icon-arrowthickstop-1-s"&gt;&lt;/span&gt;
    &lt;span&gt;download&lt;/span&gt;
    &lt;div id="content" class="ui-helper-hidden"&gt;
        &gt;K06C4.12 spliced + UTR
        ATGGCCCCACCAAAGCCGTCTGCTAAAGGAGCAAAGAAAGCCGCCAAGACCGTCACCAAGCCAAAGGACGGAAAGAAGAG
        ACGTCATGCCCGTAAAGAATCCTACTCCGTGTACATCTACCGTGTGCTCAAGCAGGTTCATCCAGACACTGGAGTCTCTT
        CCAAGGCTATGTCCATCATGAACTCTTTCGTCAACGACGTCTTCGAGCGTATCGCTGCTGAGGCATCTCGTCTTGCTCAC
        TACAACAAGAGATCCACCATCTCTTCTCGCGAAATTCAAACTGCCGTCCGTTTGATTCTTCCAGGAGAGCTTGCCAAGCA
        CGCCGTCTCTGAGGGAACCAAGGCTGTCACCAAGTACACCTCTAGCAAGTAA
    &lt;/div&gt;
    &lt;div id="filename" class="ui-helper-hidden"&gt;K06C4.12conceptual translation.fasta&lt;/div&gt;
    &lt;div id="content" class="ui-helper-hidden"&gt;
        &gt;conceptual translation
        MAPPKPSAKGAKKAAKTVTKPKDGKKRRHARKESYSVYIYRVLKQVHPDTGVSSKAMSIMNSFVNDVFERIAAEASRLAH
        YNKRSTISSREIQTAVRLILPGELAKHAVSEGTKAVTKYTSSK*
    &lt;/div&gt;
&lt;/div&gt;
&lt;div class="toggle "&gt;
    &lt;span style="float:left" class="ui-icon ui-icon-triangle-1-s"&gt;&lt;/span&gt;
    view conceptual translation (123 aa)
&lt;/div&gt;
&lt;div class="returned sequence-container" style="display:block"&gt;
    &gt;conceptual translation
    &lt;br&gt;
    MAPPKPSAKGAKKAAKTVTKPKDGKKRRHARKESYSVYIYRVLKQVHPDTGVSSKAMSIMNSFVNDVFERIAAEASRLAH
    &lt;br&gt;
    YNKRSTISSREIQTAVRLILPGELAKHAVSEGTKAVTKYTSSK*
&lt;/div&gt;


I don't find these if I simply download the page with wget and search in the source code, so they must be dynamically generated.

How could I proceed to get the sequences?

The documentation about Wormbases's REST API is not very detailed, so I don't understand how to form an URL that would give me the desired sequences.
Further inspecting the source code of the downloaded page, I found the following:

&lt;li id="nav-sequences"
    class="module-load transcript"
    wname="sequences"
    href="/rest/widget/transcript/K06C4.12/sequences"&gt;
    &lt;span class="ui-icon ui-icon-close module-close" wname="sequences"
    &lt;/span&gt;
    Sequences
&lt;/li&gt;


This suggested me to have a look at http://www.wormbase.org/rest/widget/transcript/K06C4.12/sequences and I obtained a page containing the elements found in the DOM inspector.

This can be parsed, for instance using the bs4 python module:

# To get the page
import requests
# To parse the page content
from bs4 import BeautifulSoup
# To get this into Biopython
from io import StringIO
from Bio import SeqIO

rest_template = "http://www.wormbase.org/rest/widget/transcript/{accession}/sequences"
rest = rest_template.format(accession="K06C4.12")
# This did not work with "html.parser"
soup = BeautifulSoup(requests.get(rest).text, "html5lib")

def generate_fasta(soup):
    name = None
    for div in soup.find_all("div"):
        if "ui-helper-hidden" in div["class"]:
            if div["id"] == "content":
                fasta = SeqIO.read(StringIO(div.text), "fasta")
                description_fields = fasta.description.split()
                if len(description_fields) == 4:
                    fasta.id = "_".join(description_fields[:2])
                    if name is None:
                        name = fasta.name
                elif len(description_fields) == 2:
                    # This assumes that the "conceptual_translation"
                    # is after the "unspliced + UTR" or "spliced + UTR"
                    # Otherwise, one would need to pass
                    # the accession as function parameter
                    fasta.id = f"{name}_translation"
                else:
                    fasta.id = "_".join(description_fields)
                yield (fasta.id, fasta)

records_dict = dict(generate_fasta(soup))
print(records_dict['K06C4.12_spliced'])
print(records_dict['K06C4.12_translation'])


Output:

ID: K06C4.12_spliced
Name: K06C4.12
Description: K06C4.12 spliced + UTR
Number of features: 0
Seq('ATGGCCCCACCAAAGCCGTCTGCTAAAGGAGCAAAGAAAGCCGCCAAGACCGTC...TAA', SingleLetterAlphabet())
ID: K06C4.12_translation
Name: conceptual
Description: conceptual translation
Number of features: 0
Seq('MAPPKPSAKGAKKAAKTVTKPKDGKKRRHARKESYSVYIYRVLKQVHPDTGVSS...SK*', SingleLetterAlphabet())